# /# $Id: Makefile.kmk 106916 2024-11-09 23:34:10Z vboxsync $ ## @file # Sub-Makefile for the VirtualBox User Manual, SDK reference and other manuals. # # # Copyright (C) 2006-2024 Oracle and/or its affiliates. # # This file is part of VirtualBox base platform packages, as # available from https://www.virtualbox.org. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation, in version 3 of the # License. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # SPDX-License-Identifier: GPL-3.0-only # # # This makefile produces our user manual (among a few other things) in # 3 formats: qHelp, pdf, and html (chunked and single page). User manual # files are kept in dita format. VBoxManage commands are documented using docbook # refentry elements and integrated into VBoxManage binary after converting those # to .cpp and .h files (not here). Additionally, we add these refentry's into the # user manual as a chapter after converting them into dita files. Both the user manual # and converted VBoxManage commands files are referenced with a single ditamap. # This ditamap is then transformed into html, htmlhelp (for qHelp), and pdf. # SUB_DEPTH = ../.. include $(KBUILD_PATH)/subheader.kmk ifndef VBOX_DOC_MANUAL_CONFIG_KMK_INCLUDED include $(PATH_SUB_CURRENT)/Config.kmk endif if defined(VBOX_WITH_DOCS) && (!defined(VBOX_ONLY_BUILD) || defined(VBOX_ONLY_DOCS) || defined(VBOX_ONLY_SDK)) # Whole file. # # Globals # ## Combines the VBOX_MANUAL_LANGUAGES and VBOX_MANUAL_ADD_LANGUAGES lists from # /Config.kmk, as per the VBOX_WITH_DOCS_TRANSLATIONS setting. ifdef VBOX_WITH_DOCS_TRANSLATIONS VBOX_MANUAL_ALL_LANGUAGES := $(VBOX_MANUAL_LANGUAGES) $(VBOX_MANUAL_ADD_LANGUAGES) else VBOX_MANUAL_ALL_LANGUAGES := $(VBOX_MANUAL_LANGUAGES) endif ## The files that should go into VBoxDocumentation.zip (must be immediately under PATH_STAGE_BIN). VBOX_MANUAL_PACK = # Various file lists (mainly needed for OTHER_CLEAN). VBOX_QHELP_OUTPUT_FILES := UserManual.qch UserManual.qhc VBOX_ACCESSIBILITY_XML_FILES := Accessibility.xml VBOX_MANUAL_LATEX_FILES_TARGET := $(addprefix UserManual.,aux log out toc tex) VBOX_SDKREF_LATEX_FILES_TARGET := $(addprefix SDKRef.,aux log out toc tex) VBOX_ACCESSIBILITY_LATEX_FILES_TARGET := $(addprefix Accessibility.,aux log out toc tex) VBOX_MANUAL_TEX_UNICODE_FILES = $(wildcard $(VBOX_PATH_MANUAL_SRC)/texfiles/unicode/*) # Wildcard the images path for every supported language $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES) \ ,$(eval VBOX_MANUAL_PNG_FILES_$$(lang) := $$(patsubst $$(VBOX_PATH_MANUAL_SRC)/$$(lang)/%,%, \ $$(wildcard $$(VBOX_PATH_MANUAL_SRC)/$$(lang)/images/*.png)))) # SDK related globals. VBOX_MANUAL_APIREF_TMP = $(VBOX_PATH_MANUAL_OUTBASE)/en_US/SDKRef_apiref.xml VBOX_DOC_XIDL_SRC = $(PATH_ROOT)/src/VBox/Main/idl/VirtualBox.xidl VBOX_DOC_XIDL_SRC_TMP = $(VBOX_PATH_MANUAL_OUTBASE)/en_US/VirtualBox.xidl.tmp # # PDF LaTeX related globals. # VBOX_PDFLATEX_INTERACTION ?= batchmode # VBOX_PDFLATEX_INTERACTION = errorstopmode - Use this when you wants to figure out build failures # without catting the log a million times. ifeq ($(KBUILD_HOST),win) ifndef VBOX_PDFLATEX VBOX_PDFLATEX := $(firstword $(rsort $(wildcard $(KBUILD_DEVTOOLS)/win.x86/miktex-portable/*/miktex/bin/pdflatex.exe))) ifneq ($(VBOX_PDFLATEX),) VBOX_PDFLATEX_CMD = $(VBOX_PDFLATEX) -halt-on-error -interaction $(VBOX_PDFLATEX_INTERACTION) endif endif ifndef VBOX_PDFLATEX # Tell MiKTeX to automatically download packages if system wide install. VBOX_PDFLATEX := pdflatex VBOX_PDFLATEX_CMD = $(VBOX_PDFLATEX) -halt-on-error -interaction $(VBOX_PDFLATEX_INTERACTION) --enable-installer endif else VBOX_PDFLATEX ?= pdflatex VBOX_PDFLATEX_HALT = $(shell ( $(VBOX_PDFLATEX) -version | head -1 | grep 141592 > /dev/null ) && echo -halt-on-error ) VBOX_PDFLATEX_CMD = pdflatex $(VBOX_PDFLATEX_HALT) -interaction $(VBOX_PDFLATEX_INTERACTION) endif # # Java v17 or later (JAVA_HOME), used by DITA-OT. # ifeq ($(VBOX_JAVA17PLUS_HOME),) if defined(VBOX_JAVA_VERSION) && $(VBOX_JAVA_VERSION) >= 170000 && "$(VBOX_JAVA_BIN_PATH)" != "" VBOX_JAVA17PLUS_HOME := $(qabspath ,$(VBOX_JAVA_BIN_PATH)/..) else VBOX_JAVA17PLUS_HOME := $(firstfile \ $(rversortfiles $(qwildcard , $(KBUILD_DEVTOOLS_HST)/jdk/v1[789].* $(KBUILD_DEVTOOLS_HST)/jdk/v[2-9][0-9].* )) \ $(rversortfiles $(qwildcard ,$(KBUILD_DEVTOOLS_HST_ALT)/jdk/v1[789].* $(KBUILD_DEVTOOLS_HST_ALT)/jdk/v[2-9][0-9].* )) \ ) if "$(KBUILD_HOST)" == "darwin" && "$(VBOX_JAVA17PLUS_HOME)" != "" VBOX_JAVA17PLUS_HOME := $(VBOX_JAVA17PLUS_HOME)/Contents/Home endif endif endif # # DITA-OT related globals. # VBOX_DITA_TECHNICAL_CONTENT_DTD_PATH = $(VBOX_DITA_OT_PATH)/plugins/org.oasis-open.dita.v1_2/dtd/technicalContent/dtd ## # Runs the dost.jar. # # @param 1 Additional kmk_redirect options. # @param 2 Parameters for the invoker. # VBOX_DITA_RUN_DOST = $(REDIRECT_EXT) \ -E 'ANT_HOME=$(VBOX_DITA_OT_PATH)' \ -E 'DITA_DIR=$(VBOX_DITA_OT_PATH)' \ -E 'JAVA_HOME=$(VBOX_JAVA17PLUS_HOME)' \ -E 'CLASSPATH=$(VBOX_DITA_CLASSPATH)' \ $1 \ -- \ "$(VBOX_JAVA17PLUS_HOME)/bin/java" \ "-Djava.awt.headless=true" \ "-Dsun.io.useCanonCaches=true" \ "-Dant.home=$(VBOX_DITA_OT_PATH)" \ "-Ddita.dir=$(VBOX_DITA_OT_PATH)" \ org.apache.tools.ant.launch.Launcher \ -cp "$(VBOX_DITA_CLASSPATH)" \ -buildfile "$(VBOX_DITA_OT_PATH)/build.xml" \ -main "org.dita.dost.invoker.Main" \ --args.grammar.cache=yes \ --verbose \ $(if-expr defined(VBOX_DITA_DEBUG),"--clean.temp=no" "--debug",) \ $2 VBOX_DITA_CLASSPATH = \ $(subst $(SP),$(HOST_PATH_SEP),$(strip \ $(VBOX_DITA_OT_PATH)/lib/ant-launcher.jar \ $(VBOX_DITA_OT_PATH)/config \ $(VBOX_DITA_OT_PATH)/lib \ $(wildcard \ $(VBOX_DITA_OT_PATH)/lib/*.jar \ $(VBOX_DITA_OT_PATH)/plugins/*/lib/*.jar))) # # Targets # BLDDIRS += $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/, $(VBOX_MANUAL_ALL_LANGUAGES)) ifdef VBOX_ONLY_DOCS PACKING += $(PATH_STAGE_BIN)/VBoxDocumentation.zip endif BLDDIRS += \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/topics \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/topics/images \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/topics/licensing \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/topics/licensing/vbox-base \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/topics/licensing/vbox-ext BLDDIRS += \ $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/, \ $(addsuffix /images, $(VBOX_MANUAL_ALL_LANGUAGES)) \ $(addsuffix /html-single, $(VBOX_MANUAL_ALL_LANGUAGES)) \ $(addsuffix /html-chunks, $(VBOX_MANUAL_ALL_LANGUAGES)) \ $(addsuffix /qhelp, $(VBOX_MANUAL_ALL_LANGUAGES)) \ $(addsuffix /qhelp/images, $(VBOX_MANUAL_ALL_LANGUAGES)) \ $(addsuffix /HTMLHelp, $(VBOX_MANUAL_ALL_LANGUAGES)) \ $(addsuffix /HTMLHelp/images, $(VBOX_MANUAL_ALL_LANGUAGES)) \ ) # Explicit cleaning has some overlap with default cleaning rules, since this # Makefile is using very complex conditionals for selectively creating # specific files, and not everyone remembers to use the same with "kmk clean". OTHER_CLEAN += \ $(VBOX_XML_CATALOG) \ $(VBOX_XML_CATALOG_DOCBOOK) \ $(VBOX_XML_CATALOG_DITA) \ $(VBOX_XML_CATALOG_MANUAL) \ $(VBOX_XML_ENTITIES) \ $(foreach lang, $(VBOX_MANUAL_ALL_LANGUAGES) \ ,$(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/, \ $(VBOX_XML_XREF_TO_TEXT) \ $(VBOX_XML_XREF_TO_TEXT).cat \ $(addprefix user_,$(VBOX_MANUAL_XML_REFENTRY_FILES)) \ $(VBOX_MANUAL_XML_REFENTRY_FILES) \ $(patsubst man_%,%.1,$(basename $(VBOX_MANUAL_XML_REFENTRY_FILES))) \ man_VBoxHeadless.xml \ user_man_VBoxHeadless.xml \ man_vboximg-mount.xml \ user_man_vboximg-mount.xml \ isomakercmd-man.xml \ user_isomakercmd-man.xml \ $(VBOX_MANUAL_LATEX_FILES_TARGET) \ $(VBOX_MANUAL_PNG_FILES_$(lang)) \ $(notdir $(VBOX_MANUAL_TEX_UNICODE_FILES)) \ $(addprefix HTMLHelp/,$(VBOX_MANUAL_PNG_FILES_$(lang))) \ $(addprefix qhelp/, $(VBOX_MANUAL_PNG_FILES_$(lang))) \ html-single/UserManual.html \ $(addprefix qhelp/, UserManual.qhp UserManual.qhcp $(VBOX_QHELP_OUTPUT_FILES)) \ $(addprefix HTMLHelp/, index.html go01.html) \ $(addprefix qhelp/, index.html go01.html) \ $(addprefix html-chunks/, index.html go01.html) \ $(foreach n,01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 \ ,html-chunks/ch$(n).html \ html-chunks/re$(n).html \ HTMLHelp/ch$(n).html \ HTMLHelp/re$(n).html \ $(foreach d2,0 1 2 3 4 5 6 7 8 9,$(foreach d1,0 1 2 3 4 5 6 7 8 9,HTMLHelp/ch$(n)s$(d2)$(d1).html)) \ qhelp/ch$(n).html \ qhelp/re$(n).html \ $(foreach d2,0 1 2 3 4 5 6 7 8 9,$(foreach d1,0 1 2 3 4 5 6 7 8 9,qhelp/ch$(n)s$(d2)$(d1).html)) ) \ $(foreach n,a b c \ ,html-chunks/ap$(n).html \ HTMLHelp/ap$(n).html \ $(foreach s,01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20,HTMLHelp/ap$(n)s$(s).html) \ qhelp/ap$(n).html \ $(foreach s,01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20,qhelp/ap$(n)s$(s).html) ) \ $(foreach n,01 02 03 04 05 \ ,html-chunks/pr$(n).html \ HTMLHelp/pr$(n).html \ $(foreach s,01 02 03 04 05 06 07 08,HTMLHelp/pr$(n)s$(s).html) \ qhelp/pr$(n).html \ $(foreach s,01 02 03 04 05 06 07 08,qhelp/pr$(n)s$(s).html) ) \ HTMLHelp/toc.hhc \ HTMLHelp/htmlhelp.hhp \ qhelp/toc.hhc \ qhelp/htmlhelp.hhp \ UserManual.pdf \ $(VBOX_QHELP_OUTPUT_FILES) \ ChangeLog.html \ validatemanual.run \ validateaccessibility.run \ validatesdkref.run \ ) \ ) \ $(VBOX_PATH_MANUAL_OUTBASE)/titlepage-htmlhelp.xsl \ $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/overview_,$(VBOX_MANUAL_XML_REFENTRY_FILES)) \ $(foreach f,$(VBOX_MANUAL_ADD_LANGUAGES),$(PATH_STAGE_BIN)/UserManual_$(f).pdf) \ $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_en_US) \ $(addsuffix .kmk,$(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_en_US)) \ $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES2_en_US) \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/RefEntryDITA.zip \ $(PATH_STAGE_BIN)/RefEntryDITA.zip \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ChangeLogDITA.zip \ $(PATH_STAGE_BIN)/ChangeLogDITA.zip \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/UserManual.zip \ $(PATH_STAGE_BIN)/UserManual-html.zip \ $(PATH_STAGE_BIN)/UserManual.pdf \ $(PATH_STAGE_BIN)/VBoxDocumentation.zip \ \ $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/en_US/, \ $(VBOX_SDKREF_LATEX_FILES_TARGET) \ SDKRef.pdf \ ) \ $(PATH_STAGE_BIN)/sdk/docs/SDKRef.pdf \ \ $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/en_US/, \ $(VBOX_ACCESSIBILITY_LATEX_FILES_TARGET) \ html-single/Accessibility.html \ Accessibility.pdf \ ) \ $(PATH_STAGE_BIN)/Accessibility.html \ $(PATH_STAGE_BIN)/Accessibility.pdf \ \ $(VBOX_DOC_XIDL_SRC_TMP) \ $(VBOX_MANUAL_APIREF_TMP) ifndef VBOX_ONLY_SDK # # target for installing UserManual.pdf # INSTALLS += VBox-docs-usermanual VBox-docs-usermanual_INST = $(INST_BIN) VBox-docs-usermanual_MODE = a+r,u+w VBox-docs-usermanual_SOURCES = $(VBOX_PATH_MANUAL_OUTBASE)/en_US/UserManual.pdf VBOX_MANUAL_PACK += $(PATH_STAGE_BIN)/UserManual.pdf ifdef VBOX_WITH_DOCS_TRANSLATIONS # # target for installing translated UserManual_*.pdf # INSTALLS += VBox-docs-usermanual-l10n VBox-docs-usermanual-l10n_INST = $(INST_BIN) VBox-docs-usermanual-l10n_MODE = a+r,u+w VBox-docs-usermanual-l10n_SOURCES = \ $(foreach f,$(VBOX_MANUAL_ADD_LANGUAGES),$(VBOX_PATH_MANUAL_OUTBASE)/$(f)/UserManual.pdf=>UserManual_$(f).pdf) VBOX_MANUAL_PACK += $(foreach f,$(VBOX_MANUAL_ADD_LANGUAGES),$(PATH_STAGE_BIN)/UserManual_$(f).pdf) endif ifdef VBOX_WITH_DOCS_HTML # # target for installing the chunked HTML docs # INSTALLS += VBox-docs-usermanual-html VBox-docs-usermanual-html_INST = $(INST_BIN) VBox-docs-usermanual-html_MODE = a+r,u+w VBox-docs-usermanual-html_SOURCES = $(VBOX_PATH_MANUAL_OUTBASE)/en_US/UserManual.zip=>UserManual-html.zip VBOX_MANUAL_PACK += $(PATH_STAGE_BIN)/UserManual-html.zip endif ifdef VBOX_WITH_DOCS_QHELP # # Installs the qhelp version of the manual. # INSTALLS += VBox-docs-usermanual-qhelp VBox-docs-usermanual-qhelp_INST = $(INST_BIN) VBox-docs-usermanual-qhelp_MODE = a+r,u+w VBox-docs-usermanual-qhelp_SOURCES = \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/qhelp/UserManual.qhc \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/qhelp/UserManual.qch ifdef VBOX_WITH_DOCS_QHELP_PACKING VBOX_MANUAL_PACK += \ $(PATH_STAGE_BIN)/UserManual.qch \ $(PATH_STAGE_BIN)/UserManual.qhc endif endif ifdef VBOX_WITH_DOCS_USERMANUAL_REFENTRY_DITA # # target for installing the ZIP containing the manpages in DITA format # INSTALLS += VBox-docs-usermanual-refentry-dita VBox-docs-usermanual-refentry-dita_INST = $(INST_BIN) VBox-docs-usermanual-refentry-dita_MODE = a+r,u+w VBox-docs-usermanual-refentry-dita_SOURCES = $(VBOX_PATH_MANUAL_OUTBASE)/en_US/RefEntryDITA.zip VBOX_MANUAL_PACK += $(PATH_STAGE_BIN)/RefEntryDITA.zip endif ifdef VBOX_WITH_DOCS_USERMANUAL_CHANGELOG_DITA # # target for installing the ZIP containing the change log in DITA format # INSTALLS += VBox-docs-usermanual-changelog-dita VBox-docs-usermanual-changelog-dita_INST = $(INST_BIN) VBox-docs-usermanual-changelog-dita_MODE = a+r,u+w VBox-docs-usermanual-changelog-dita_SOURCES = $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ChangeLogDITA.zip VBOX_MANUAL_PACK += $(PATH_STAGE_BIN)/ChangeLogDITA.zip endif ifdef VBOX_WITH_DOCS_ACCESSIBILITY # # target for installing Accessibility.pdf # INSTALLS += VBox-docs-accessibility VBox-docs-accessibility_INST = $(INST_BIN) VBox-docs-accessibility_MODE = a+r,u+w VBox-docs-accessibility_SOURCES = $(VBOX_PATH_MANUAL_OUTBASE)/en_US/Accessibility.pdf # # target for installing Accessibility.html # INSTALLS += VBox-docs-accessibility-html VBox-docs-accessibility-html_INST = $(INST_BIN) VBox-docs-accessibility-html_MODE = a+r,u+w VBox-docs-accessibility-html_SOURCES = $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-single/Accessibility.html endif endif # !VBOX_ONLY_SDK if defined(VBOX_ONLY_SDK) || defined(VBOX_WITH_DOCS_SDKREF) # # target for installing SDKRef.pdf # INSTALLS += VBox-docs-sdkref VBox-docs-sdkref_INST = $(INST_SDK)docs/ VBox-docs-sdkref_MODE = a+r,u+w VBox-docs-sdkref_SOURCES = $(VBOX_PATH_MANUAL_OUTBASE)/en_US/SDKRef.pdf endif # # Shared rules for LaTeX based PDF generation - Only used for SDK & Accessibility. # ifndef VBOX_OSE # Copy ucs.sty and associated files. ## @todo r=bird: This is ugly since only ucs.sty is listed as output while we're actually copying 177 other files. $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/ucs.sty): | $$(dir $$@) $(call MSG_L1,Copying unicode support for LaTeX) $(QUIET)$(INSTALL_STAGING) -m0644 -- $(VBOX_MANUAL_TEX_UNICODE_FILES) "$(@D)" endif # Copy the PNG files. define def_vbox_cp_images_pdf $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/,$(VBOX_MANUAL_PNG_FILES_$(lang))): \ $(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/% : \ $(VBOX_PATH_MANUAL_SRC)/$(lang)/% | $$$$(dir $$$$@) $$(call MSG_L1,Copying temporary $$< => $$@) $$(QUIET)$$(INSTALL_STAGING) -m0644 -- '$$<' '$$(@D)' endef $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(evalcall2 def_vbox_cp_images_pdf)) ################################################################################################################################# # SDKRef.pdf - xidl => Docbook => LaTeX => PDF # ################################################################################################################################# VBOX_SDKREF_XML_FILES = SDKRef.xml # Replace @a and @c with tags in VirtualBox.xidl. $(VBOX_DOC_XIDL_SRC_TMP): $(VBOX_DOC_XIDL_SRC) $(MAKEFILE_CURRENT) | $$(dir $$@) $(call MSG_L1,Generating $@) $(QUIET)$(SED) \ -e 's|@a \+\(\w\+\)|\1|g' \ -e 's|@c \+\(\w\+\)|\1|g' \ --output $@ $< # Generate SDKRef_apiref.xml as a docbook file excerpt that will be referenced from the SDKRef.xml. $(VBOX_MANUAL_APIREF_TMP): $(VBOX_PATH_MANUAL_SRC)/xidl2docbook.xsl $(VBOX_DOC_XIDL_SRC_TMP) $(call MSG_L1,Generating $@) $(QUIET)$(VBOX_XSLTPROC) $(VBOX_XSLTPROC_OPTS) --xinclude --nonet -o $@ $< $(VBOX_DOC_XIDL_SRC_TMP) # Turn SDKRef.xml into LaTeX. $(VBOX_PATH_MANUAL_OUTBASE)/en_US/SDKRef.tex: \ $(addprefix $(VBOX_PATH_MANUAL_SRC)/en_US/,$(VBOX_SDKREF_XML_FILES)) \ $(VBOX_MANUAL_APIREF_TMP) \ $(VBOX_PATH_MANUAL_SRC)/docbook2latex.xsl \ $(if $(VBOX_HAVE_XMLLINT),$(VBOX_PATH_MANUAL_OUTBASE)/en_US/validatesdkref.run,) \ $(VBOX_XML_ALL_CATALOGS_DEP) \ $(VBOX_XML_ENTITIES) \ $(MAKEFILE_CURRENT) \ | $$(dir $$@) $(call MSG_TOOL,xsltproc $(notdir $(filter %.xsl,$^)),,$(firstword $(filter %.xml,$^)),$@) $(QUIET)$(RM) -f $(addprefix $(@D/),$(VBOX_SDKREF_LATEX_FILES_TARGET)) # generate TeX source from processed docbook and store it in SDKRef.tex.tmp $(QUIET)$(call VBOX_XSLTPROC_WITH_CAT) --stringparam TARGETLANG en_US \ -o $@.tmp $(VBOX_PATH_MANUAL_SRC)/docbook2latex.xsl $< # for pretty quotes, replace " with `` or '' depending on whether it's at the start of a word; # the \QUOTE{} was inserted by docbook2latex.xsl for all quotes _outside_ of screen sections $(QUIET)$(SED) \ -e 's|^\\QUOTE{}|\\OQ{}|g' \ -e 's|\(\W\)\\QUOTE{}|\1\\OQ{}|g' \ -e 's|\(\w\)\\QUOTE{}|\1\\CQ{}|g' \ --output $@ $@.tmp $(QUIET)$(RM) -f $@.tmp # Turn SDKRef.tex into a PDF. $(VBOX_PATH_MANUAL_OUTBASE)/en_US/SDKRef.pdf: \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/SDKRef.tex \ $(if $(VBOX_OSE),,$(VBOX_PATH_MANUAL_OUTBASE)/en_US/ucs.sty) \ $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/en_US/,$(VBOX_MANUAL_PNG_FILES_en_US)) \ | $$(dir $$@) $(call MSG_L1,pdflatex $< (three passes)) $(QUIET)$(REDIRECT) -C $( LaTeX => PDF # ################################################################################################################################# # Turn Accessibility.xml into LaTeX. $(VBOX_PATH_MANUAL_OUTBASE)/en_US/Accessibility.tex: \ $(addprefix $(VBOX_PATH_MANUAL_SRC)/en_US/,$(VBOX_ACCESSIBILITY_XML_FILES)) \ $(VBOX_PATH_MANUAL_SRC)/docbook2latex.xsl \ $(if $(VBOX_HAVE_XMLLINT),$(VBOX_PATH_MANUAL_OUTBASE)/en_US/validateaccessibility.run,) \ $(VBOX_XML_ALL_CATALOGS_DEP) \ $(VBOX_XML_ENTITIES) \ $(MAKEFILE_CURRENT) \ | $$(dir $$@) $(call MSG_TOOL,xsltproc $(notdir $(filter %.xsl,$^)),,$(firstword $(filter %.xml,$^)),$@) $(QUIET)$(RM) -f $(addprefix $(@D/),$(VBOX_ACCESSIBILITY_LATEX_FILES_TARGET)) # generate TeX source from processed docbook and store it in Accessibility.tex.tmp $(QUIET)$(call VBOX_XSLTPROC_WITH_CAT) --stringparam TARGETLANG en_US \ -o $@.tmp $(VBOX_PATH_MANUAL_SRC)/docbook2latex.xsl $< # for pretty quotes, replace " with `` or '' depending on whether it's at the start of a word; # the \QUOTE{} was inserted by docbook2latex.xsl for all quotes _outside_ of screen sections $(QUIET)$(SED) \ -e 's|^\\QUOTE{}|\\OQ{}|g' \ -e 's|\(\W\)\\QUOTE{}|\1\\OQ{}|g' \ -e 's|\(\w\)\\QUOTE{}|\1\\CQ{}|g' \ --output $@ $@.tmp $(QUIET)$(RM) -f $@.tmp # Turn Accessibility.tex into a PDF. $(VBOX_PATH_MANUAL_OUTBASE)/en_US/Accessibility.pdf: \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/Accessibility.tex \ $(if $(VBOX_OSE),,$(VBOX_PATH_MANUAL_OUTBASE)/en_US/ucs.sty) \ $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/en_US/,$(VBOX_MANUAL_PNG_FILES_en_US)) $(call MSG_L1,pdflatex $< (three passes)) $(QUIET)$(REDIRECT) -C $(/dita/* to the corresponding # VBOX_PATH_MANUAL_OUTBASE location. This is mainly to deal with DITO-OT's # inability to search for topic files in more than one place, so we have to # gather generated and static topic sources + the .ditamap-file(s) in one # place. # # Determine the basic set of files as dictated by the en_US version of the # user manual (relative to $(lang)/dita). We'll use these to supply # incomplete manual translations. # Note! This includes .png as well as .dita and .ditamap files. VBOX_USER_MANUAL_DITA_BASIC_SRC_FILES := \ $(notdir $(wildcard $(VBOX_PATH_MANUAL_SRC)/en_US/dita/*.dita*)) \ $(addprefix topics/,$(notdir $(wildcard $(VBOX_PATH_MANUAL_SRC)/en_US/dita/topics/*dita))) \ $(addprefix topics/images/,$(notdir $(wildcard $(VBOX_PATH_MANUAL_SRC)/en_US/dita/topics/images/*png))) \ $(addprefix topics/licensing/,$(notdir $(wildcard $(VBOX_PATH_MANUAL_SRC)/en_US/dita/topics/licensing/*dita*))) \ $(addprefix topics/licensing/vbox-base/,$(notdir $(wildcard $(VBOX_PATH_MANUAL_SRC)/en_US/dita/topics/licensing/vbox-base/*dita))) \ $(addprefix topics/licensing/vbox-ext/,$(notdir $(wildcard $(VBOX_PATH_MANUAL_SRC)/en_US/dita/topics/licensing/vbox-ext/*dita))) ## # Produce copying rules for one language and defining the variable # VBOX_USER_MANUAL_DITA_STAGED_FILES_ for use in prerequisite to # anything producing a version of the user manual. # # @param 1 lang define def_vbox_copy_manual_dita_src_files VBOX_USER_MANUAL_DITA_SRC_FILES_$(1) := \ $$(notdir $$(wildcard $$(VBOX_PATH_MANUAL_SRC)/$1/dita/*.ditamap)) \ $$(addprefix topics/,$$(notdir $$(wildcard $$(VBOX_PATH_MANUAL_SRC)/$1/dita/topics/*dita))) \ $$(addprefix topics/images/,$$(notdir $$(wildcard $$(VBOX_PATH_MANUAL_SRC)/$1/dita/topics/images/*png))) \ $$(addprefix topics/licensing/,$$(notdir $$(wildcard $$(VBOX_PATH_MANUAL_SRC)/$1/dita/topics/licensing/*dita*))) \ $$(addprefix topics/licensing/vbox-base/,$$(notdir $$(wildcard $$(VBOX_PATH_MANUAL_SRC)/$1/dita/topics/licensing/vbox-base/*dita))) \ $$(addprefix topics/licensing/vbox-ext/,$$(notdir $$(wildcard $$(VBOX_PATH_MANUAL_SRC)/$1/dita/topics/licensing/vbox-ext/*dita))) VBOX_USER_MANUAL_DITA_SRC_FILES_$(1)_FALLBACK := \ $$(filter-out $$(VBOX_USER_MANUAL_DITA_SRC_FILES_$(1)), $$(VBOX_USER_MANUAL_DITA_BASIC_SRC_FILES)) VBOX_USER_MANUAL_DITA_STAGED_FILES_$(1) = \ $$(addprefix $$(VBOX_PATH_MANUAL_OUTBASE)/$1/dita/, \ $$(VBOX_USER_MANUAL_DITA_SRC_FILES_$(1)) \ $$(VBOX_USER_MANUAL_DITA_SRC_FILES_$(1)_FALLBACK) ) ifneq ($$(VBOX_USER_MANUAL_DITA_SRC_FILES_$(1)),) $$(addprefix $$(VBOX_PATH_MANUAL_OUTBASE)/$1/dita/,$$(VBOX_USER_MANUAL_DITA_SRC_FILES_$(1))): \ $$(VBOX_PATH_MANUAL_OUTBASE)/$1/dita/% : \ $$(VBOX_PATH_MANUAL_SRC)/$1/dita/% | $$$$(dir $$$$@) $$(QUIET)$$(INSTALL_STAGING) -m 0644 -- "$$<" "$$(@D)/" endif ifneq ($$(VBOX_USER_MANUAL_DITA_SRC_FILES_$(1)_FALLBACK),) $$(addprefix $$(VBOX_PATH_MANUAL_OUTBASE)/$1/dita/,$$(VBOX_USER_MANUAL_DITA_SRC_FILES_$(1)_FALLBACK)): \ $$(VBOX_PATH_MANUAL_OUTBASE)/$1/dita/% : \ $$(VBOX_PATH_MANUAL_SRC)/en_US/dita/% | $$$$(dir $$$$@) $$(QUIET)$$(INSTALL_STAGING) -m 0644 -- "$$<" "$$(@D)/" endif endef $(foreach lang, $(VBOX_MANUAL_ALL_LANGUAGES),$(evalcall2 def_vbox_copy_manual_dita_src_files,$(lang))) # # 2. Convert the manpages from Docbook refentry files to DITA reference files. # # In DITA links needs proper href values, with both file and ID. Since the # source only has IDs, we scan all topics and refentry-files alike and # generate a mapping database before we start converting them. This DB is # then used at the end of each conversion to fix the hrefs. # ## # Do per-language stuff for the refentry -> dita file conversion. # # The variable VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_ is defined # by this define and should be expanded as a prerequisite for any rule # producing a version of the user manual. # # @param 1 Language. # define def_vbox_refentry_to_dita # Generate a ID to FILE mapping database that def_vbox_refentry_to_dita can apply below. VBOX_USER_MANUAL_ID_MAPPING_FILE_$(1) := $$(VBOX_PATH_MANUAL_OUTBASE)/$1/id-mapping-file.db OTHER_CLEAN += $(VBOX_USER_MANUAL_ID_MAPPING_FILE_$(1)) $$(VBOX_USER_MANUAL_ID_MAPPING_FILE_$(1)) + $$(VBOX_USER_MANUAL_ID_MAPPING_FILE_$(1)).lst: \ $$(VBOX_PATH_MANUAL_SRC)/build_id_to_file_mapping.py \ $$(wildcard $$(VBOX_PATH_MANUAL_SRC)/$1/*.xml) \ $$(filter %.dita,$$(VBOX_USER_MANUAL_DITA_STAGED_FILES_$(1))) \ | $$$$(dir $$$$@) $$(call MSG_L1, $$<) $$(QUIET)$$(APPEND) -nt "$$@.lst" $$(filter-out %.py,$$^) $$(QUIET)$$(VBOX_BLD_PYTHON) "$$<" --output "$$@" @"$$@.lst" # Accumulated list of conversion output file names to be used as a # prerequisite in rules producing a version of the user manual. VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_$1 := endef # def_vbox_refentry_to_dita ## Convert a single refentry file to dita. # @param 1 Language # @param 2 Filename w/o extension. # @param 3 Alternative fallback filename (for isomakercmd-man.xml). # @note This produces more files than listed in the output, but we currently let kmk be ignorant of that. define def_vbox_refentry_file_to_dita VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_$1 += $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/$(2).ditamap $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/$(2).ditamap \ + $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/$(2).ditamap.kmk \ + $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).dita \ + $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).xml: \ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manual-dita-pre.xsl \ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manual-dita.xsl \ $$(VBOX_PATH_MANUAL_SRC)/dita-refentry-flat-to-single-topic.sh \ $$(VBOX_PATH_MANUAL_SRC)/dita-refentry-flat-to-single-topic.xsl \ $$(VBOX_PATH_MANUAL_SRC)/dita-refentry-flat-topic-ids.xsl \ $$(VBOX_PATH_MANUAL_SRC)/add_file_to_id_only_references.py \ $$(VBOX_USER_MANUAL_ID_MAPPING_FILE_$1) \ $$(qfirstfile , $$(qwildcard , $$(VBOX_PATH_MANUAL_SRC)/$(1)/$(2).xml) $(3) $$(VBOX_PATH_MANUAL_SRC)/en_US/$(2).xml) \ $$(VBOX_XML_ALL_CATALOGS_DEP) \ $$(VBOX_XML_ENTITIES) \ $$(VBOX_VERSION_STAMP) \ | $$$$(dir $$$$@) $$(call MSG_TOOL,xsltproc docbook-refentry-to-manual-dita[-pre].xsl,,$$(firstword $$(filter %.xml,$$^)),$$@) $$(QUIET)$$(RM) -f -- "$$@" \ "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).xml" \ "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).dita" $$(QUIET)$$(call VBOX_XSLTPROC_WITH_CAT) \ --output "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).xml" \ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manual-dita-pre.xsl \ $$(qfirstfile , $$(qwildcard , $$(VBOX_PATH_MANUAL_SRC)/$(1)/$(2).xml) $(3) $$(VBOX_PATH_MANUAL_SRC)/en_US/$(2).xml) $$(QUIET)$$(call VBOX_XSLTPROC_WITH_CAT) \ --stringparam "g_fReplaceHyphens" "true" \ --output "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).dita" \ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manual-dita.xsl \ "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).xml" $$(QUIET)$$(VBOX_BLD_PYTHON) $$(VBOX_PATH_MANUAL_SRC)/add_file_to_id_only_references.py \ --mapping-file "$$(VBOX_USER_MANUAL_ID_MAPPING_FILE_$1)" \ "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).dita" $$(QUIET)$$(ASH) \ "$$(VBOX_PATH_MANUAL_SRC)/dita-refentry-flat-to-single-topic.sh" \ "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).dita" \ "$$(VBOX_PATH_MANUAL_SRC)/dita-refentry-flat-topic-ids.xsl" \ "$$(VBOX_PATH_MANUAL_SRC)/dita-refentry-flat-to-single-topic.xsl" \ "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/$(2).ditamap.kmk" \ "VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES2_$(1)" \ "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics" \ -- $$(subst $$(REDIRECT),$$(REDIRECT_EXT),$$(call VBOX_XSLTPROC_WITH_CAT)) $(VBOX_XSLTPROC_WORKAROUND) \ --path "$$(VBOX_DITA_TECHNICAL_CONTENT_DTD_PATH)" $$(QUIET)$$(call VBOX_XSLTPROC_WITH_CAT) $(VBOX_XSLTPROC_WORKAROUND) \ --path "$$(VBOX_DITA_TECHNICAL_CONTENT_DTD_PATH)" \ --stringparam g_sMode map \ --output "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/$(2).ditamap" \ $$(VBOX_PATH_MANUAL_SRC)/dita-refentry-flat-to-single-topic.xsl \ "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/flat-$(2).dita" endef # def_vbox_refentry_file_to_dita $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES) \ ,$(evalcall2 def_vbox_refentry_to_dita,$(lang)) \ $(foreach file, $(basename $(VBOX_MANUAL_XML_REFENTRY_FILES) man_vboximg-mount man_VBoxHeadless) \ ,$(evalcall2 def_vbox_refentry_file_to_dita,$(lang),$(file))) \ $(evalcall2 def_vbox_refentry_file_to_dita,$(lang),user_isomakercmd-man, \ $(PATH_ROOT)/src/VBox/Runtime/common/fs/isomakercmd-man.xml)) ifdef VBOX_ONLY_DOCS include $(VBOX_PATH_MANUAL_OUTBASE)/refentry.kmk $(VBOX_PATH_MANUAL_OUTBASE)/refentry.kmk: \ $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES) \ ,$(VBOX_PATH_MANUAL_OUTBASE)/refentry_$(lang).kmk) $(QUIET)$(RM) -f -- "$@" $(APPEND) -tn "$@" '# refentry.kmk' $(APPEND) -n "$@" $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),'include $(VBOX_PATH_MANUAL_OUTBASE)/refentry_$(lang).kmk') $(APPEND) -n "$@" '# done' ## Include file for all language specific refentry files. # @param 1 Language define def_vbox_refentry_lang_kmk $$(VBOX_PATH_MANUAL_OUTBASE)/refentry_$(1).kmk: \ $$(addsuffix .kmk,$$(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_$(1))) $$(QUIET)$$(RM) -f -- "$$@" $$(APPEND) -tn "$$@" '# refentry_$(1).kmk' $$(APPEND) -n "$$@" $$(addprefix 'include ,$$(addsuffix .kmk',$$(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_$(1)))) $$(APPEND) -n "$$@" '# done' endef # def_vbox_refentry_lang_kmk $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES) \ ,$(evalcall2 def_vbox_refentry_lang_kmk,$(lang))) endif # Run conversion testcase. refentry-to-dita-test: $(RM) -f -- \ "$(VBOX_PATH_MANUAL_OUTBASE)/testcase-refentry1.xml" \ "$(VBOX_PATH_MANUAL_OUTBASE)/testcase-refentry1.dita" $(call VBOX_XSLTPROC_WITH_CAT) \ --output "$(VBOX_PATH_MANUAL_OUTBASE)/testcase-refentry1.xml" \ $(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manual-dita-pre.xsl \ $(VBOX_PATH_MANUAL_SRC)/testcase/refentry1.xml $(call VBOX_XSLTPROC_WITH_CAT) \ --output "$(VBOX_PATH_MANUAL_OUTBASE)/testcase-refentry1.dita" \ $(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manual-dita.xsl \ "$(VBOX_PATH_MANUAL_OUTBASE)/testcase-refentry1.xml" $(VBOX_PATH_MANUAL_OUTBASE)/en_US/RefEntryDITA.zip: \ $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_en_US) \ $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES2_en_US) \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/topics/vboxmanage-cmd-overview.dita $(call MSG_L1,Packing documentation $@) $(QUIET)$(RM) -f $@ $(QUIET)$(REDIRECT) -C $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ -- $(VBOX_ZIP) \ -9 -r "$@" \ $(patsubst $(VBOX_PATH_MANUAL_OUTBASE)/en_US/%,%,$^) refentry-dita-zip:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/RefEntryDITA.zip # # 2b. Generate the VBoxManage commands overview topic based upon the # command synopis dita files generated in the above step. # # @param 1 Language define def_vbox_generate_vboxmanage_overview VBOX_USER_MANUAL_DITA_STAGED_FILES_$1 += $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/vboxmanage-cmd-overview.dita $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/vboxmanage-cmd-overview.dita \ + $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/vboxmanage-cmd-overview.dita.files.xml: \ $$(VBOX_PATH_MANUAL_SRC)/$(1)/vboxmanage-cmd-overview.xsl \ $$(VBOX_PATH_MANUAL_SRC)/vboxmanage-cmd-overview.xsl \ $$(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_$(1)) \ | $$$$(dir $$$$@) $$(call MSG_TOOL,xsltproc vboxmanage-cmd-overview.dita.xsl,,,$$@) $$(QUIET)$$(RM) -f -- "$$@" "$$@.files.xml" $$(APPEND) -tn "$$@.files.xml" '' '' $$(SED) -n \ -e 's/^.*topicref .*topics\/man_VBoxManage-\([^.]*\)\.ditamap.*$$(DOLLAR)/vboxmanage-\1-synopsis.dita<\/file>/p' \ --append "$$@.files.xml" \ $(VBOX_PATH_MANUAL_SRC)/$(1)/dita/UserManual.ditamap $$(APPEND) -n "$$@.files.xml" '' $$(QUIET)$$(call VBOX_XSLTPROC_WITH_CAT) $(VBOX_XSLTPROC_WORKAROUND) --path "$$(VBOX_DITA_TECHNICAL_CONTENT_DTD_PATH)" \ --output "$$@" \ $$(VBOX_PATH_MANUAL_SRC)/$(1)/vboxmanage-cmd-overview.xsl \ "$$@.files.xml" endef # def_vbox_generate_vboxmanage_overview $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(evalcall2 def_vbox_generate_vboxmanage_overview,$(lang))) # # 3. Convert the changelog from DocBook to a bunch of DITA topics and corresponding map. # ## # @param 1 Language # @note We don't really need to do this for each language, but whatever. # @note Outputs a bunch of .dita files for each version too... define def_vbox_convert_changelog_to_dita VBOX_USER_MANUAL_DITA_STAGED_FILES_$1 += $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/changelog-versions.ditamap $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/changelog-versions.ditamap \ + $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics/changelog-versions.ditamap.kmk: \ $$(VBOX_PATH_MANUAL_SRC)/docbook-changelog-to-manual-dita.sh \ $$(VBOX_PATH_MANUAL_SRC)/docbook-changelog-to-manual-dita.xsl \ $$(VBOX_XML_ALL_CATALOGS_DEP) \ | $$$$(dir $$$$@) $$(call MSG_TOOL,xsltproc docbook-changelog-to-manual-dita.xsl,,,$$@) $$(QUIET)$$(RM) -f -- "$$@" "$$@.files.xml" $$(QUIET)$$(ASH) \ $$(VBOX_PATH_MANUAL_SRC)/docbook-changelog-to-manual-dita.sh \ $$(VBOX_PATH_MANUAL_SRC)/user_ChangeLogImpl.xml \ $$(VBOX_PATH_MANUAL_SRC)/docbook-changelog-to-manual-dita.xsl \ $$(@).kmk \ VBOX_USER_MANUAL_CONVERTED_CHANGELOG_DITA_FILES_$(1) \ $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/topics \ -- \ $$(call VBOX_XSLTPROC_WITH_CAT) endef # def_vbox_convert_changelog_to_dita $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(evalcall2 def_vbox_convert_changelog_to_dita,$(lang))) ifdef VBOX_ONLY_DOCS include $(VBOX_PATH_MANUAL_OUTBASE)/changelog.kmk $(VBOX_PATH_MANUAL_OUTBASE)/changelog.kmk: \ $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES) \ ,$(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/dita/topics/changelog-versions.ditamap.kmk) $(QUIET)$(RM) -f -- "$@" $(APPEND) -tn "$@" '# changelog.kmk' $(APPEND) -n "$@" $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),'include $(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/dita/topics/changelog-versions.ditamap.kmk') $(APPEND) -n "$@" '# done' endif $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ChangeLogDITA.zip: \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/topics/changelog-versions.ditamap \ $(VBOX_USER_MANUAL_CONVERTED_CHANGELOG_DITA_FILES_en_US) $(call MSG_L1,Packing documentation $@) $(QUIET)$(RM) -f $@ $(QUIET)$(REDIRECT) -C $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ -- $(VBOX_ZIP) \ -9 -r "$@" \ $(patsubst $(VBOX_PATH_MANUAL_OUTBASE)/en_US/%,%,$^) changelog-dita-zip:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ChangeLogDITA.zip # # 4a. UserManual.pdf - Run dost.jar from DITA-OT to produce the PDF version. # # Note! The --temp (dir) is deleted, recreated, used and deleted again for each # run. So, be careful where you point it. # Note! This crappy utility may fail to find files (or fail to parse the # command line) and still return a successfully (0) exit code. # define def_ditamap_to_pdf $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/UserManual.pdf \ + $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/UserManual_pdf.log \ +| $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita.list \ +| $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita.xml.properties: \ $$(VBOX_MANUAL_XML_FILES_COMMON) \ $$(VBOX_MANUAL_XML_FILES_GENERATED_$(lang)) \ $$(VBOX_USER_MANUAL_DITA_STAGED_FILES_$(lang)) \ $$(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_$(lang)) \ $$(VBOX_PATH_MANUAL_SRC)/pdf-theme-UserManual.yaml \ $$(VBOX_PATH_MANUAL_SRC)/en_US/images/vboxlogo.svg $$(call MSG_L1,Building $$@ ($$(@D)/UserManual_pdf.log)) $$(QUIET)$$(RM) -f -- "$$@" $$(QUIET)$$(RM) -Rf -- "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/temp_pdf" $$(QUIET)$$(call VBOX_DITA_RUN_DOST,, \ "--input=$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/UserManual.ditamap" \ "--format=pdf" \ "--filter=$$(VBOX_PATH_MANUAL_SRC)/$(1)/dita/ohc.ditaval" \ "--output=$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)" \ "--temp=$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/temp_pdf" \ "--theme=$$(VBOX_PATH_MANUAL_SRC)/pdf-theme-UserManual.yaml" \ "--logfile=$$(@D)/UserManual_pdf.log" \ ) ditamap-to-pdf: $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/UserManual.pdf .PRECIOUS: $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/UserManual_pdf.log endef $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(evalcall2 def_ditamap_to_pdf,$(lang))) # Useful aliases usermanual UserManual.pdf:: $(PATH_STAGE_BIN)/UserManual.pdf # # 4b. UserManual.html - Run dost.jar from DITA-OT to produce the HTML versions. # # We produce both chunked and singled paged HTML versions of the en_US manual # mainly for uploading to virtualbox.org. The docs build box produces a zip # including these. # ## @todo front page $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-chunks/index.html: \ $(VBOX_USER_MANUAL_DITA_STAGED_FILES_en_US) \ $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_en_US) $(QUIET)$(RM) -Rf -- "$(@D)" \ "$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/temp_xhtml_chunks" $(call MSG_L1,Building html chunks $@ ($(@D)/UserManual_xhtml.log)) $(QUIET)$(MKDIR) -- "$(@D)" $(QUIET)$(call VBOX_DITA_RUN_DOST,, \ "--input=$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/UserManual.ditamap" \ "--format=xhtml" \ "--filter=$(VBOX_PATH_MANUAL_SRC)/en_US/dita/htmlhelp.ditaval" \ "--output=$(@D)" \ "--temp=$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/temp_xhtml_chunks" \ "--logfile=$(@D)/UserManual_xhtml.log" \ "--store-type=memory" \ ) html:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-chunks/index.html # We must modify UserManual.ditamap here, removing all chunk attributes and put # a chunk="to-content" on the root element (bookmap). For clues see: # https://docs.oasis-open.org/dita/v1.2/os/spec/archSpec/chunking.html # https://www.oxygenxml.com/forum/post25114.html?hilit=dita%20xhtml%20chunk#p25114 # We stich the index.html and UserManual-Single.html files together using # SED since we haven't been able to convince DITA-OT to combine them. # ## @todo This is excruciatingly slow with 4.0.2 because of a preprocessing step # (move-meta in the org.dita.base plugin) is doing 986 read+writes of # the singled combined dita document (XML). This is probably the two # for loops in the pushMetadata() method in # src/main/java/org/dita/dost/module/MoveMetaModule.java. The netbeans # profiler says that ouf 283 sec runtime, 64 secs are spent reading # the xml big doc and 212 secs spent writing it out again (212+64=276). # # For the chunked version, the move-meta work is done on each .ditamap # and .dita (topic) file instead, which is a lot less expensive. # # The problem is forced by the AbstractDomFilter.read() design, which # reads XML to DOM, modifies DOM, writes out DOM as XML. The # modifications done by the DitaMetaWriter.process function is # restricted to a single topic, which is means this must be done this # way. # # A workaround, though, would be to implement a custom cache that # cache the document and doesn't write it to disk until the loops # finishes. This could build on the CacheStore.java code, only # potential challenge is to clone the job as the Job.store property is # immutable. # ## @todo front page $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-single/UserManual.html: \ $(VBOX_USER_MANUAL_DITA_STAGED_FILES_en_US) \ $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_en_US) $(call MSG_L1,Building html chunks $@ ($(@D)/UserManual-Single_xhtml.log)) $(QUIET)$(RM) -Rf -- "$(@D)" \ "$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita-ot-html-single/" \ "$(VBOX_PATH_MANUAL_OUTBASE)/en_US/dita/UserManual-Single.ditamap" $(SED) -r -e 's/ chunk=["][^"]+["]//g' -e 's//{p}' \ --output "$@" "$(@D)/UserManual-Single.html" $(APPEND) -n "$@" "" $(SED) -ne '//,/<\/body>/{//d;/<\/body>/d;s/UserManual-Single.html/UserManual.html/g;p}' \ --append "$@" "$(@D)/index.html" $(APPEND) -n "$@" "" $(SED) -ne '//,99999999{//d;s/UserManual-Single.html/UserManual.html/g;p}' \ --append "$@" "$(@D)/UserManual-Single.html" html:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-single/UserManual.html $(VBOX_PATH_MANUAL_OUTBASE)/en_US/UserManual.zip: \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-chunks/index.html \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/html-single/UserManual.html $(call MSG_L1,Packing documentation $@) $(QUIET)$(RM) -f $@ $(QUIET)$(REDIRECT) -C $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ -- $(VBOX_ZIP) \ -9 -r "$@" \ "html-chunks" \ "html-single" \ -x "html-chunks/dita.list" \ -x "html-chunks/dita.xml.properties" \ -x "html-chunks/UserManual_xhtml.log" \ -x "html-single/dita.list" \ -x "html-single/dita.xml.properties" \ -x "html-single/UserManual-Single_xhtml.log" \ -x "html-single/index.html" \ -x "html-single/UserManual-Single.html" html-zip:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/UserManual.zip # # A few things which are shared between htmlhelp and qhelp docs. # TODO: This is Docbook related work. Left here in case we can reuse some of # the ideas from it for DITA-OT. # VBOX_DOCBOOK_HTMLHELP_FORMATCFG = \ $(VBOX_PATH_MANUAL_SRC)/docbook-htmlhelp-formatcfg.xsl \ $(VBOX_PATH_MANUAL_SRC)/common-formatcfg.xsl \ $(VBOX_PATH_MANUAL_SRC)/common-html-formatcfg.xsl # Prepare the XSL file for our title page, htmlhelp and qhelp variant. $(VBOX_PATH_MANUAL_OUTBASE)/titlepage-htmlhelp.xsl: \ $(VBOX_PATH_MANUAL_SRC)/titlepage-htmlhelp.xml $(MAKEFILE_CURRENT) | $$(dir $$@) $(call MSG_L1,xsltproc $<) $(QUIET)$(RM) -f $@.tmp $@ $(QUIET)$(VBOX_XSLTPROC) --xinclude --nonet -o $@.tmp $(VBOX_PATH_DOCBOOK)/template/titlepage.xsl $< $(QUIET)$(MV) -f $@.tmp $@ # end old stuff. if defined(VBOX_WITH_DOCS_QHELP) && !defined(VBOX_ONLY_SDK) # # 4c. VirtualBox.qch + VirtualBox.qhc - Qt compressed help and collection file. # # See usermanual.pdf under DITA-OT-xxxxx/doc folder for details. # # Enable Qt and locate the Qt help generator. USES += qt6 VBOX_QHELPGENERATOR = $(PATH_TOOL_QT6_LIBEXEC)/qhelpgenerator ## Build QHelp version of manual for given language. # @param 1 Language # @param 2 The language specific qhelp output directory. define def_vbox_usermanual_as_qhelp # 1. Generate UserManual.hpp using DITA-OT. # # Setting HHCDIR here so that it fails to locate hcc.exe and always skips the # compilation step that produces the .chm-file, since we don't need it and it # mangles the path so it always fails anyway. # # HACK ALERT! Putting MSG_L1 between RM and MKDIR as the latter sometimes fails # on windows because the deleted directory still exists on Windows. # # HACK ALERT! For 4.0.2 we must set Ant property dita.output.dir to the output # dir to prevent the *.hhp+*.html+*.png files from being placed in # the temporary directory and removed upon completion (idea being # that hhc.exe had run and the files weren't needed any more - the # htmlhelp plugin sets temp.output.dir.name to 'temp_chm_dir'). # ## @todo front page. $(2)/UserManual.hhp: \ $(VBOX_USER_MANUAL_DITA_STAGED_FILES_$(1)) \ $(VBOX_USER_MANUAL_CONVERTED_REFENTRY_DITA_FILES_$(1)) $$(QUIET)$$(RM) -Rf -- "$$(@D)" \ "$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/temp_qhelp" $$(call MSG_L1,dita-ot-qhelp, => $$@ ($(2)/UserManual_htmlhelp.log)) $$(QUIET)$$(MKDIR) -- "$$(@D)" $$(QUIET)$$(call VBOX_DITA_RUN_DOST, -EHHCDIR="$$(@D)", \ "--input=$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/UserManual.ditamap" \ "--format=htmlhelp" \ "--filter=$$(VBOX_PATH_MANUAL_SRC)/$(1)/dita/htmlhelp.ditaval" \ "--output=$(2)" \ "--temp=$$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/dita/temp_qhelp" \ "--logfile=$(2)/UserManual_htmlhelp.log" \ "-Ddita.output.dir=$(2)" \ ) $$(QUIET)$$(MV) -f -- "$(2)/UserManual.hhc" "$(2)/UserManual.hhc.tmp" $$(QUIET)$$(SED) \ -e 's|®|®|g' \ -e 's|windows-1252|utf-8|g' \ --output "$(2)/UserManual.hhc" "$(2)/UserManual.hhc.tmp" $$(QUIET)$$(RM) -f -- "$(2)/UserManual.hhc.tmp" ditamap-to-htmlhelp: $(2)/UserManual.hhp # 2. Generate a Qt Help Project file (QHP) using htmlhelp-qthelp.py. $(2)/UserManual.qhp: \ $(2)/UserManual.hhp \ $$(VBOX_PATH_MANUAL_SRC)/htmlhelp-qthelp.py $$(call MSG_L1,htmlhelp-qthelp.py $$<,=> $$@) $$(QUIET)$$(RM) -f -- "$$@" $$(QUIET)$$(VBOX_BLD_PYTHON) $$(VBOX_PATH_MANUAL_SRC)/htmlhelp-qthelp.py \ -d "$$( $$@ ($(2)/UserManual_htmlhelp.log)) $$(QUIET)$$(INSTALL) -m0644 -- '$$<' '$$(@D)' # 4. Run the Qt help generator to produce the .qhc and .qch files. $(2)/UserManual.qch \ + $(2)/UserManual.qhc: \ $(2)/UserManual.qhcp \ $(2)/UserManual.qhp $$(call MSG_L1,$$(notdir $$(VBOX_QHELPGENERATOR)) $$<,=> $$@) $$(QUIET)$$(RM) -f -- "$$@" $$(QUIET)$$(REDIRECT) -E "QT_PLUGIN_PATH=$$(PATH_SDK_QT6)/plugins" -E "QT_QPA_PLATFORM_PLUGIN_PATH=$$(PATH_SDK_QT6)/plugins/platforms" -- $$(VBOX_QHELPGENERATOR) $$< $$(call MSG_L1,Fresh QCH is now at $$@) endef # def_vbox_usermanual_as_qhelp $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES) \ ,$(evalcall2 def_vbox_usermanual_as_qhelp,$(lang),$(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/qhelp)) qhelp:: $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/en_US/qhelp/, $(VBOX_QHELP_OUTPUT_FILES)) endif # VBOX_WITH_DOCS_QHELP && !VBOX_ONLY_SDK ################################################################################################################################# # Miscellaneous # ################################################################################################################################# # # ChangeLog.html # # This XSLT rule formats en_US/user_ChangeLog.xml (which includes the actual change log # contained in user_ChangeLogImpl.xml) as a standalone HTML file. # $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ChangeLog.html: \ $(VBOX_PATH_MANUAL_SRC)/en_US/docbook-changelog-formatcfg.xsl \ $(VBOX_PATH_MANUAL_OUTBASE)/en_US/user_ChangeLog.xml \ $(VBOX_XML_ALL_CATALOGS_DEP) \ $(VBOX_XML_ENTITIES) | $$(dir $$@) $(call MSG_TOOL,xsltproc $(notdir $(firstword $(filter %.xsl,$^))),,$(firstword $(filter %.xml,$^)),$@) $(QUIET)$(call VBOX_XSLTPROC_WITH_CAT) --output "$@" "$<" $(filter %.xml,$^) $(call MSG_L1,Fresh ChangeLog.html is now at $@) cl-html:: $(VBOX_PATH_MANUAL_OUTBASE)/en_US/ChangeLog.html # # VBoxManage man pages (parts also required by VBoxManage built-in help). # ## # Emits rules for preprocessing refentry sources (applying remarks element), # and for producing the actual man pages. # $(evalcall2 def_vbox_refentry_to_manpage) # @param 1 The language # @param 2 The file name (no path). define def_vbox_refentry_to_manpage $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/$(2): \ $$(VBOX_PATH_MANUAL_SRC)/$(1)/$(2) \ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manpage-preprocessing.xsl \ $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/$$(VBOX_XML_XREF_TO_TEXT) \ $$(VBOX_XML_ALL_CATALOGS_DEP) \ $$(VBOX_XML_ENTITIES) $$(VBOX_VERSION_STAMP) | $$$$(dir $$$$@) $$(call MSG_TOOL,xsltproc $$(notdir $$(firstword $$(filter %.xsl,$$^))),,$$(firstword $$(filter %.xml,$$^)),$$@) $$(QUIET)$$(RM) -f "$$@" $$(QUIET)$$(call VBOX_XSLTPROC_WITH_CAT) --output $$@ \ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manpage-preprocessing.xsl $$< $$(QUIET)$$(call VBOX_XSLTPROC_WITH_CAT) --output $$@.tmp $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/$$(VBOX_XML_XREF_TO_TEXT) $$@ $$(QUIET)$$(MV) -f -- "$$@.tmp" "$$@" if defined(VBOX_HAVE_XMLLINT) $$(VBOX_XMLLINT_WITH_CAT) --dtdvalid $$(VBOX_PATH_DOCBOOK_DTD)/docbookx.dtd $$@ endif $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/$(patsubst man_%,%.1,$(basename $(2))): \ $$(VBOX_PATH_MANUAL_OUTBASE)/$(1)/$(2) \ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manpage.xsl \ $$(VBOX_XML_ALL_CATALOGS_DEP) \ $$(VBOX_XML_ENTITIES) $$(VBOX_VERSION_STAMP) | $$$$(dir $$$$@) $$(call MSG_TOOL,xsltproc $$(notdir $$(firstword $$(filter %.xsl,$$^))),,$$(firstword $$(filter %.xml,$$^)),$$@) $$(QUIET)$$(RM) -f "$$@" $$(QUIET)$$(call VBOX_XSLTPROC_WITH_CAT) --maxdepth 6000 --output $$@ $$(VBOX_PATH_MANUAL_SRC)/docbook-refentry-to-manpage.xsl $$< endef $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(foreach file,$(VBOX_MANUAL_XML_REFENTRY_FILES) \ , $(evalcall2 def_vbox_refentry_to_manpage,$(lang),$(file)))) # Handy aliases. validate-manpages:: $(addprefix $(VBOX_PATH_MANUAL_OUTBASE)/en_US/,$(VBOX_MANUAL_XML_REFENTRY_FILES)) man-experiment:: $(foreach lang,$(VBOX_MANUAL_ALL_LANGUAGES),$(foreach file,$(VBOX_MANUAL_XML_REFENTRY_FILES) \ ,$$(VBOX_PATH_MANUAL_OUTBASE)/$(lang)/$(patsubst man_%,%.1,$(basename $(file))))) # # Manually updating the DHCP option list taken from VirtualBox.xidl # dhcpoptions: $(PATH_ROOT)/doc/manual/en_US/man_VBoxManage-dhcpserver-dhcpoptions.xsl \ $(PATH_ROOT)/src/VBox/Main/idl/VirtualBox.xidl $(call VBOX_XSLTPROC) --stringparam g_uVBoxCopyrightYear "$(VBOX_C_YEAR)" \ --output "$(PATH_ROOT)/doc/manual/en_US/man_VBoxManage-dhcpserver-dhcpoptions.xml" $^ # # Packing the docs into a zip file (part of the packing pass on the docs build box). # ifneq ($(VBOX_MANUAL_PACK),) $(PATH_STAGE_BIN)/VBoxDocumentation.zip: $(VBOX_MANUAL_PACK) $(call MSG_L1,Packing documentation $@) $(QUIET)$(RM) -f $@ $(QUIET)$(REDIRECT) -C $(PATH_STAGE_BIN) -- $(VBOX_ZIP) -9 $@ $(notdir $^) endif endif # if defined(VBOX_WITH_DOCS) && (!defined(VBOX_ONLY_BUILD) || defined(VBOX_ONLY_DOCS) || defined(VBOX_ONLY_SDK)) include $(FILE_KBUILD_SUB_FOOTER)