MantisBT - CMake
View Issue Details
0014925CMakeCPackpublic2014-05-22 09:192016-06-10 14:31
Richard Ulrich 
Nils Gladitz 
normalfeaturealways
closedmoved 
CMake 2.8.12.2 
 
0014925: Generate Multilanguage msi files with the WiX generator
When I first saw that CPACK_WIX_CULTURES accepts a list, I assumed it would build a multilanguage package.
Later I learned, that the behavior comes from WiX itself, that it builds a package for the first culture entry, and uses the others as backup if a certain string is not available for the primary culture.
At first, I read on the WiX Tutorial, that msi packages are always single culture. But then I found out the procedure to make them multilanguage. It's a bit cumbersome:
* build an msi for each culture
* make a diff for each of them
* inject the diffs into the main msi
* tell the msi which cultures it supports

I created a custom target that creates a multilanguage msi for me.
But it would be much nicer, if this could be baked into cpack.
# build a separate msi for each of the different supported languages
# generate *.mst (transform) files of the diffs # inject the transforms into the german installer
# http://www.codeproject.com/Articles/103749/Creating-a-Localized-Windows-Installer-Bootstrap [^]
GET_FILENAME_COMPONENT(CPACK_COMMAND ${CMAKE_COMMAND} PATH)
SET(CPACK_COMMAND ${CPACK_COMMAND}/cpack.exe)
FILE(WRITE ${PROJECT_BINARY_DIR}/WixMultiLang.bat "@echo off" \n)
# build the english installer
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat ":: building the installer in english" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${CMAKE_COMMAND}\" -D CPACK_WIX_CULTURES:STRING=en-us \"${PointLine_MAIN_DIR}\"" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${CPACK_COMMAND}\" -G WIX -C RelWithDebInfo" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "del ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_en-us.msi" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "ren ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_en-us.msi" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
# build the dutch installer
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat ":: building the installer in dutch" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${CMAKE_COMMAND}\" -D CPACK_WIX_CULTURES:STRING=nl-nl \"${PointLine_MAIN_DIR}\"" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${CPACK_COMMAND}\" -G WIX -C RelWithDebInfo" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "del ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_nl-nl.msi" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "ren ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_nl-nl.msi" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
# build the french installer
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat ":: building the installer in french" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${CMAKE_COMMAND}\" -D CPACK_WIX_CULTURES:STRING=fr-fr \"${PointLine_MAIN_DIR}\"" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${CPACK_COMMAND}\" -G WIX -C RelWithDebInfo" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "del ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_fr-fr.msi" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "ren ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_fr-fr.msi" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
# build the german installer
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat ":: building the installer in german" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${CMAKE_COMMAND}\" -D CPACK_WIX_CULTURES:STRING=de-de \"${PointLine_MAIN_DIR}\"" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${CPACK_COMMAND}\" -G WIX -C RelWithDebInfo" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
# make diffs and generate the transforms
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat ":: generating the transforms from the diffs" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${WIX_TORCH}\" ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_en-us.msi -o ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_en-us.mst" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${WIX_TORCH}\" ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_nl-nl.msi -o ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_nl-nl.mst" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${WIX_TORCH}\" ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_fr-fr.msi -o ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_fr-fr.mst" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "@echo sucessfully generated the language transforms" \n)
# inject the diffs into the german installer
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat ":: injecting the transforms into the german installer" \n)
SET(MSWSWDEVKIT_CSCRIPT cscript.exe) # Windows Script Host
SET(MSWSWDEVKIT_WiSubStg ${PointLine_MAIN_DIR}/Installer/WiX/WiSubStg.vbs) # From Microsoft Windows SDK for Windows
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${MSWSWDEVKIT_CSCRIPT}\" \"${MSWSWDEVKIT_WiSubStg}\" ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_en-us.mst 1033" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${MSWSWDEVKIT_CSCRIPT}\" \"${MSWSWDEVKIT_WiSubStg}\" ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_nl-nl.mst 1043" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${MSWSWDEVKIT_CSCRIPT}\" \"${MSWSWDEVKIT_WiSubStg}\" ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32_fr-fr.mst 1036" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "@echo sucessfully injected the language transforms" \n)
# tell the installer, which localizations it contains
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat ":: tell the installer, which localizations it contains" \n)
SET(MSWSWDEVKIT_WiLangId ${PointLine_MAIN_DIR}/Installer/WiX/wilangid.vbs) # From Microsoft Windows SDK for Windows
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "\"${MSWSWDEVKIT_CSCRIPT}\" \"${MSWSWDEVKIT_WiLangId}\" ${CPACK_PACKAGE_NAME}-${VERSION_STR3}-win32.msi Package 1031,1033,1043,1036" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "if %ERRORLEVEL% neq 0 goto exit" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat "@echo sucessfully injected the localization information" \n)
FILE(APPEND ${PROJECT_BINARY_DIR}/WixMultiLang.bat ":exit" \n)

ADD_CUSTOM_TARGET(WiX_LangTransforms
        COMMAND ${PROJECT_BINARY_DIR}/WixMultiLang.bat
        WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
        COMMENT "build the msi for the different supported languages, and generate mst (transform) files of the diffs"
)
No tags attached.
Issue History
2014-05-22 09:19Richard UlrichNew Issue
2014-05-22 09:42Nils GladitzAssigned To => Nils Gladitz
2014-05-22 09:42Nils GladitzStatusnew => assigned
2015-06-12 02:23Richard UlrichNote Added: 0038914
2016-06-10 14:29Kitware RobotNote Added: 0042549
2016-06-10 14:29Kitware RobotStatusassigned => resolved
2016-06-10 14:29Kitware RobotResolutionopen => moved
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0038914)
Richard Ulrich   
2015-06-12 02:23   
If the different language specific installers could be built in parallel, It could signifficantly reduce the total build time.
(0042549)
Kitware Robot   
2016-06-10 14:29   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.