#
# Copyright 2003-2019 the Pacemaker project contributors
#
# The version control history for this file may have further details.
#
# This source code is licensed under the GNU General Public License version 2
# or later (GPLv2+) WITHOUT ANY WARRANTY.
#
include $(top_srcdir)/mk/common.mk
# Deprecated plaintext documents (dynamically converted to HTML)
DEPRECATED_ORIGINAL = crm_fencing.txt
DEPRECATED_GENERATED =
if BUILD_ASCIIDOC
DEPRECATED_GENERATED += $(DEPRECATED_ORIGINAL:%.txt=%.html)
endif
DEPRECATED_ALL = $(DEPRECATED_ORIGINAL) $(DEPRECATED_GENERATED)
# Current documentation based on asciidoc, DocBook, and pandoc
BOOKS = Clusters_from_Scratch \
Pacemaker_Administration \
Pacemaker_Development \
Pacemaker_Explained \
Pacemaker_Remote
doc_DATA = $(DEPRECATED_ALL)
noinst_SCRIPTS = abi-check
# The sphinx docs are not yet built by default, but we still want to distribute
# them so configure can build the Makefile in a distribution.
DIST_SUBDIRS = sphinx
EXTRA_DIST = $(DEPRECATED_ORIGINAL) $(SHARED_TXT) $(PNGS_ORIGINAL) $(DOTS) $(SVGS)
EXTRA_DIST += $(CFS_TXT) $(CFS_XML_ONLY)
EXTRA_DIST += $(PA_TXT) $(PA_XML_ONLY)
EXTRA_DIST += $(PD_TXT) $(PD_XML_ONLY)
EXTRA_DIST += $(PE_TXT) $(PE_XML_ONLY)
EXTRA_DIST += $(PR_TXT) $(PR_XML_ONLY)
EXTRA_DIST += pcs-crmsh-quick-ref.md
# toplevel rsync destination for www targets (without trailing slash)
RSYNC_DEST ?= root@www.clusterlabs.org:/var/www/html
# recursive, preserve symlinks/permissions/times, verbose, compress,
# don't cross filesystems, sparse, show progress
RSYNC_OPTS = -rlptvzxS --progress
LAST_RELEASE ?= Pacemaker-$(VERSION)
TAG ?= $(shell [ -n "`git tag --points-at HEAD | head -1`" ] \
&& ( git tag --points-at HEAD | head -1 ) \
|| git log --pretty=format:%H -n 1 HEAD)
# What formats to build by default: pdf,html,html-single,html-desktop,epub
DOCBOOK_FORMATS := html-desktop
# What languages to build and upload to website by default
# (currently only en-US because translations are out of date)
DOCBOOK_LANGS := en-US
# @TODO We could simplify this (and .gitignore) by establishing a convention
# that original image source begins with an uppercase letter and generated
# files with lowercase.
# Scheduler transition graphs
# @TODO Add original XML, and generate DOTs via crm_simulate
DOTS = $(wildcard shared/en-US/images/*.dot)
# Vector sources for images
# @TODO Generate transition SVGs from DOTs via dot
SVGS = $(wildcard shared/en-US/images/pcmk-*.svg) \
$(DOTS:%.dot=%.svg)
# Final images (some originally in PNG, others generated from SVG)
PNGS_ORIGINAL = Pacemaker_Remote/en-US/images/pcmk-ha-cluster-stack.png \
Pacemaker_Remote/en-US/images/pcmk-ha-remote-stack.png \
shared/en-US/images/Console.png \
shared/en-US/images/Editing-eth0.png \
shared/en-US/images/Installer.png \
shared/en-US/images/Network.png \
shared/en-US/images/Partitioning.png \
shared/en-US/images/Welcome.png \
shared/en-US/images/resource-set.png \
shared/en-US/images/three-sets.png \
shared/en-US/images/two-sets.png
PNGS_GENERATED = $(SVGS:%.svg=%-small.png) \
$(SVGS:%.svg=%.png) \
$(SVGS:%.svg=%-large.png)
PNGS = $(PNGS_ORIGINAL) $(PNGS_GENERATED)
graphics: $(PNGS)
# two-phased attempts for Inkscape pre-1.0 and 1.0+ (upcoming) discrepancy
%.png: %.svg
$(AM_V_GEN) { $(INKSCAPE) --export-dpi=90 -C --export-png=$@ $< \
|| $(INKSCAPE) --export-dpi=90 -C --export-filename=$@ $<; } $(PCMK_quiet)
%-small.png: %.svg
$(AM_V_GEN) { $(INKSCAPE) --export-dpi=45 -C --export-png=$@ $< \
|| $(INKSCAPE) --export-dpi=45 -C --export-filename=$@ $<; } $(PCMK_quiet)
%-large.png: %.svg
$(AM_V_GEN) { $(INKSCAPE) --export-dpi=180 -C --export-png=$@ $< \
|| $(INKSCAPE) --export-dpi=180 -C --export-filename=$@ $<; } $(PCMK_quiet)
if IS_ASCIIDOC
ASCIIDOC_HTML_ARGS = --unsafe --backend=xhtml11
ASCIIDOC_DBOOK_ARGS = -b docbook -d book
else
ASCIIDOC_HTML_ARGS = --backend=html5
ASCIIDOC_DBOOK_ARGS = -b docbook45 -d book
endif
%.html: %.txt
$(AM_V_GEN)$(ASCIIDOC_CONV) $(ASCIIDOC_HTML_ARGS) --out-file=$@ $< $(PCMK_quiet)
#
# Generate DocBook XML from asciidoc text.
#
# Build each chapter as a book (since the numbering isn't right for
# articles and only books can have appendices) and then strip out the
# bits we don't want or need.
#
# XXX Sequence of tr/sed commands should be replaced with a single XSLT
#
%.xml: %.txt
$(AM_V_at)$(MKDIR_P) $(shell dirname $@) # might not exist in VPATH build
$(AM_V_at)$(ASCIIDOC_CONV) $(ASCIIDOC_DBOOK_ARGS) -o - $< | tr -d '\036\r' >$@-t # Convert, fix line endings
$(AM_V_at)sed -i 's/\ lang="en"//' $@-t # Never specify a language in the chapters
$(AM_V_at)sed -i 's/simpara/para/g' $@-t # publican doesn't correctly render footnotes with simpara
$(AM_V_at)sed -i 's/.*<date>.*//g' $@-t # Remove dangling tag
$(AM_V_at)sed -i 's/.*preface>//g' $@-t # Remove preface elements
$(AM_V_at)sed -i 's:<title></title>::g' $@-t # Remove empty title
$(AM_V_at)sed -i 's/chapter/section/g' $@-t # Chapters become sections, so that books can become chapters
$(AM_V_at)sed -i 's/<.*bookinfo.*>//g' $@-t # Strip out bookinfo, we don't need it
$(AM_V_at)! grep -q "<appendix" $@-t || sed -i \
's/.*book>//;tb;bf;:b;N;s/.*<title>.*<\/title>.*//;tb;/<appendix/{:i;n;/<\/appendix/{p;d};bi};bb;:f;p;d' \
$@-t # We just want the appendix tag (asciidoctor adds non-empty book-level title)
$(AM_V_at)sed -i 's/book>/chapter>/g' $@-t # Rename to chapter (won't trigger if previous sed did)
$(AM_V_GEN)mv $@-t $@
# For Makefile debugging
.PHONY: vars
vars:
@echo DEPRECATED_ORIGINAL=\'$(DEPRECATED_ORIGINAL)\'
@echo DEPRECATED_GENERATED=\'$(DEPRECATED_GENERATED)\'
@echo BOOKS=\'$(BOOKS)\'
@echo LAST_RELEASE=\'$(LAST_RELEASE)\'
@echo TAG=\'$(TAG)\'
.PHONY: deprecated-upload
deprecated-upload: $(DEPRECATED_ALL)
rsync $(RSYNC_OPTS) $(DEPRECATED_ALL) "$(RSYNC_DEST)/$(PACKAGE)/doc/"
.PHONY: deprecated-clean
deprecated-clean:
-rm -f $(DEPRECATED_GENERATED)
# publican-clusterlabs/xsl/{html,html-single,pdf}.xsl refer to URIs
# requiring Internet access, hence we shadow that with a XML catalog-based
# redirect to local files brought with Publican installation;
# this is what newer Publican normally does with the system-wide catalog
# upon its installation, but let's provide a compatibility for older
# or badly installed instances (via adding the created file into
# XML_CATALOG_FILES for libxml2 backing Publican as a fallback);
# note that nextCatalog arrangement needed so as to overcome
# https://rt.cpan.org/Public/Bug/Display.html?id=113781
publican-catalog-fallback:
@exec >$@-t \
&& echo '<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">' \
&& echo '<rewriteURI uriStartString="https://fedorahosted.org/released/publican/xsl/docbook4/" rewritePrefix="file:///usr/share/publican/xsl/"/>' \
&& echo '</catalog>'
$(AM_V_GEN)mv $@-t $@
publican-catalog: publican-catalog-fallback
@exec >$@-t \
&& echo '<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">' \
&& echo '<nextCatalog catalog="file:///etc/xml/catalog"/>' \
&& echo '<nextCatalog catalog="file://$(CURDIR)/$<"/>' \
&& echo '</catalog>'
$(AM_V_GEN)mv $@-t $@
COMMON_XML = Author_Group.xml Book_Info.xml Revision_History.xml
SHARED_TXT=$(wildcard shared/en-US/*.txt)
SHARED_XML=$(SHARED_TXT:%.txt=%.xml)
if PUBLICAN_INTREE_BRAND
PUBLICAN_INTREE_DEPS = publican-catalog
PUBLICAN_INTREE_ENV = XML_CATALOG_FILES="$(CURDIR)/publican-catalog"
PUBLICAN_INTREE_OPT = --brand_dir="$(top_srcdir)/publican-clusterlabs"
else
PUBLICAN_INTREE_DEPS =
PUBLICAN_INTREE_ENV =
PUBLICAN_INTREE_OPT =
endif
# Clusters From Scratch
CFS_SHARED_TXT = $(addprefix shared/en-US/,pacemaker-intro.txt)
CFS_SHARED_XML = $(CFS_SHARED_TXT:%.txt=%.xml)
CFS_TXT = $(wildcard Clusters_from_Scratch/en-US/*.txt)
CFS_XML_GEN = $(CFS_TXT:%.txt=%.xml)
CFS_XML_ONLY = $(addprefix $(srcdir)/Clusters_from_Scratch/en-US/,$(COMMON_XML) \
Clusters_from_Scratch.ent \
Clusters_from_Scratch.xml \
Preface.xml)
CFS_DEPS = $(PNGS) $(CFS_SHARED_XML) $(CFS_XML_ONLY) $(CFS_XML_GEN)
# We have to hardcode the book name
# With '%' the test for 'newness' fails
Clusters_from_Scratch.build: $(CFS_DEPS) $(PUBLICAN_INTREE_DEPS)
@echo "Building $(@:%.build=%) because of $?"
rm -rf "$(@:%.build=%)/publish"/* "$(@:%.build=%)/tmp"
$(AM_V_PUB)cd $(@:%.build=%) && RPM_BUILD_DIR="" $(PUBLICAN_INTREE_ENV) \
$(PUBLICAN) build --src_dir="$(srcdir)" --publish \
--langs="$(DOCBOOK_LANGS)" --formats="$(DOCBOOK_FORMATS)" \
$(PUBLICAN_INTREE_OPT) $(PCMK_quiet)
rm -rf "$(@:%.build=%)/tmp"
touch "$@"
# Pacemaker Administration
PA_TXT = $(wildcard Pacemaker_Administration/en-US/*.txt)
PA_XML_GEN = $(PA_TXT:%.txt=%.xml)
PA_XML_ONLY = $(addprefix $(srcdir)/Pacemaker_Administration/en-US/,$(COMMON_XML) \
Pacemaker_Administration.ent \
Pacemaker_Administration.xml \
Preface.xml)
PA_DEPS = $(PA_XML_ONLY) $(PA_XML_GEN)
# We have to hardcode the book name
# With '%' the test for 'newness' fails
Pacemaker_Administration.build: $(PA_DEPS) $(PUBLICAN_INTREE_DEPS)
@echo Building $(@:%.build=%) because of $?
rm -rf $(@:%.build=%)/publish/*
$(AM_V_PUB)cd $(@:%.build=%) && RPM_BUILD_DIR="" $(PUBLICAN_INTREE_ENV) \
$(PUBLICAN) build --src_dir="$(srcdir)" --publish \
--langs="$(DOCBOOK_LANGS)" --formats="$(DOCBOOK_FORMATS)" \
$(PUBLICAN_INTREE_OPT) $(PCMK_quiet)
rm -rf $(@:%.build=%)/tmp
touch "$@"
# Pacemaker Development
PD_TXT = $(wildcard Pacemaker_Development/en-US/*.txt)
PD_XML_GEN = $(PD_TXT:%.txt=%.xml)
PD_XML_ONLY = $(addprefix $(srcdir)/Pacemaker_Development/en-US/,$(COMMON_XML) \
Pacemaker_Development.ent \
Pacemaker_Development.xml)
PD_DEPS = $(PD_XML_ONLY) $(PD_XML_GEN)
# We have to hardcode the book name
# With '%' the test for 'newness' fails
Pacemaker_Development.build: $(PD_DEPS) $(PUBLICAN_INTREE_DEPS)
@echo Building $(@:%.build=%) because of $?
rm -rf $(@:%.build=%)/publish/* $(@:%.build=%)/tmp
$(AM_V_PUB)cd $(@:%.build=%) && RPM_BUILD_DIR="" $(PUBLICAN_INTREE_ENV) \
$(PUBLICAN) build --src_dir="$(srcdir)" --publish \
--langs="$(DOCBOOK_LANGS)" --formats="$(DOCBOOK_FORMATS)" \
$(PUBLICAN_INTREE_OPT) $(PCMK_quiet)
rm -rf $(@:%.build=%)/tmp
touch "$@"
# Pacemaker Explained
PE_SHARED_TXT = $(addprefix shared/en-US/,pacemaker-intro.txt)
PE_SHARED_XML = $(PE_SHARED_TXT:%.txt=%.xml)
PE_TXT = $(wildcard Pacemaker_Explained/en-US/*.txt)
PE_XML_GEN = $(PE_TXT:%.txt=%.xml)
PE_XML_ONLY = $(addprefix $(srcdir)/Pacemaker_Explained/en-US/,$(COMMON_XML) \
Pacemaker_Explained.ent \
Pacemaker_Explained.xml \
Preface.xml)
PE_DEPS = $(PNGS) $(PE_SHARED_XML) $(PE_XML_ONLY) $(PE_XML_GEN)
# We have to hardcode the book name
# With '%' the test for 'newness' fails
Pacemaker_Explained.build: $(PE_DEPS) $(PUBLICAN_INTREE_DEPS)
@echo Building $(@:%.build=%) because of $?
rm -rf $(@:%.build=%)/publish/* $(@:%.build=%)/tmp
$(AM_V_PUB)cd $(@:%.build=%) && RPM_BUILD_DIR="" $(PUBLICAN_INTREE_ENV) \
$(PUBLICAN) build --src_dir="$(srcdir)" --publish \
--langs="$(DOCBOOK_LANGS)" --formats="$(DOCBOOK_FORMATS)" \
$(PUBLICAN_INTREE_OPT) $(PCMK_quiet)
rm -rf $(@:%.build=%)/tmp
touch "$@"
# Pacemaker Remote
PR_TXT = $(wildcard Pacemaker_Remote/en-US/*.txt)
PR_XML_GEN = $(PR_TXT:%.txt=%.xml)
PR_XML_ONLY = $(addprefix $(srcdir)/Pacemaker_Remote/en-US/,$(COMMON_XML) \
Pacemaker_Remote.ent \
Pacemaker_Remote.xml)
PR_DEPS = $(PNGS) $(PR_XML_ONLY) $(PR_XML_GEN)
# We have to hardcode the book name
# With '%' the test for 'newness' fails
Pacemaker_Remote.build: $(PR_DEPS) $(PUBLICAN_INTREE_DEPS)
@echo Building $(@:%.build=%) because of $?
rm -rf $(@:%.build=%)/publish/* $(@:%.build=%)/tmp
$(AM_V_PUB)cd $(@:%.build=%) && RPM_BUILD_DIR="" $(PUBLICAN_INTREE_ENV) \
$(PUBLICAN) build --src_dir="$(srcdir)" --publish \
--langs="$(DOCBOOK_LANGS)" --formats="$(DOCBOOK_FORMATS)" \
$(PUBLICAN_INTREE_OPT) $(PCMK_quiet)
rm -rf $(@:%.build=%)/tmp
touch "$@"
# Build all books for upload to ClusterLabs
.PHONY: books
books: books-clean
if BUILD_DOCBOOK
for book in $(BOOKS); do \
sed -i.sed 's@^brand:.*@brand: clusterlabs@' $$book/publican.cfg; \
done
$(MAKE) $(AM_MAKEFLAGS) DOCBOOK_FORMATS="pdf,html,html-single,epub" \
DOCBOOK_LANGS="$(DOCBOOK_LANGS)" all-local
endif
.PHONY: books-upload
books-upload: books
if BUILD_DOCBOOK
@echo Uploading current $(PACKAGE_SERIES) documentation set to clusterlabs.org
@for book in $(BOOKS); do \
echo Uploading $$book...; \
echo "Generated on `date` from version: $(shell git log --pretty="format:%h %d" -n 1)" \
>> $$book/publish/build-$(PACKAGE_SERIES).txt; \
rsync $(RSYNC_OPTS) $$book/publish/* "$(RSYNC_DEST)/$(PACKAGE)/doc/"; \
done
endif
.PHONY: books-clean
books-clean:
-for book in $(BOOKS); do \
rm -rf $$book/tmp $$book/publish; \
done
-rm -f $(PNGS_GENERATED) \
$(SHARED_XML) \
$(CFS_XML_GEN) \
$(PA_XML_GEN) \
$(PD_XML_GEN) \
$(PE_XML_GEN) \
$(PR_XML_GEN) \
publican-catalog-fallback \
publican-catalog
if BUILD_DOCBOOK
all-local: $(BOOKS:%=%.build) */publican.cfg
install-data-local: all-local
for book in $(BOOKS); do \
filelist=`find $$book/publish/* -print`; \
for f in $$filelist; do \
p=`echo $$f | sed s:publish/:: | sed s:Pacemaker/::`; \
if [ -d $$f ]; then \
$(INSTALL) -d -m 775 $(DESTDIR)$(docdir)/$$p; \
else \
$(INSTALL) -m 644 $$f $(DESTDIR)$(docdir)/$$p; \
fi \
done; \
done
endif
BRAND_DEPS = $(wildcard publican-clusterlabs/en-US/*.png) \
$(wildcard publican-clusterlabs/en-US/*.xml)
brand-build: $(BRAND_DEPS)
cd publican-clusterlabs && publican build --formats=xml --langs=all --publish
brand: brand-build
@echo "Installing branded content..."
cd publican-clusterlabs && sudo publican install_brand --path=$(datadir)/publican/Common_Content
brand-rpm-clean:
-find publican-clusterlabs -name "*.noarch.rpm" -exec rm -f \{\} \;
brand-rpm-build: brand-rpm-clean brand-build
cd publican-clusterlabs && \
$(PUBLICAN) --src_dir="$(srcdir)" package --binary
brand-rpm-install: brand-rpm-build
find publican-clusterlabs -name "*.noarch.rpm" -exec sudo rpm -Uvh --force \{\} \;
pdf:
$(MAKE) $(AM_MAKEFLAGS) DOCBOOK_FORMATS="pdf" all-local
# Annotated source code as HTML
global:
$(MAKE) $(AM_MAKEFLAGS) -C .. clean-generic
cd .. && gtags -q && htags -sanhIT doc
global-upload: global
rsync $(RSYNC_OPTS) HTML/ "$(RSYNC_DEST)/$(PACKAGE)/global/$(TAG)/"
global-clean:
-rm -rf HTML
# Man pages as HTML
%.8.html: %.8
groff -mandoc `man -w ./$<` -T html > $@
%.7.html: %.7
groff -mandoc `man -w ./$<` -T html > $@
manhtml:
$(MAKE) $(AM_MAKEFLAGS) -C .. all
find .. -name "[a-z]*.[78]" -exec $(MAKE) $(AM_MAKEFLAGS) \{\}.html \;
manhtml-upload: manhtml
find .. -name "[a-z]*.[78].html" -exec \
rsync $(RSYNC_OPTS) \{\} "$(RSYNC_DEST)/$(PACKAGE)/man/" \;
manhtml-clean:
-find .. -name "[a-z]*.[78].html" -exec rm \{\} \;
# API documentation as HTML
doxygen: Doxyfile
doxygen Doxyfile
doxygen-upload: doxygen
rsync $(RSYNC_OPTS) api/html/ "$(RSYNC_DEST)/$(PACKAGE)/doxygen/$(TAG)/"
doxygen-clean:
-rm -rf api
# ABI compatibility report as HTML
abi: abi-check
./abi-check $(PACKAGE) $(LAST_RELEASE) $(TAG)
abi-www:
export RSYNC_DEST=$(RSYNC_DEST); ./abi-check -u $(PACKAGE) $(LAST_RELEASE) $(TAG)
abi-clean:
-rm -rf abi_dumps compat_reports
# All HTML documentation (except ABI compatibility, which is run separately)
.PHONY: www
www: clean-local deprecated-upload manhtml-upload global-upload doxygen-upload books-upload
clean-local: brand-rpm-clean global-clean manhtml-clean doxygen-clean abi-clean books-clean deprecated-clean