[CMake] Mac and Win32 bundling
Filip Wänström
filip.wanstrom at tii.se
Tue Nov 24 09:23:56 EST 2009
Hi my name is Filip Wänström and I'm new to this list.
I have recently(a few months) started to use CMake for all my
building. I find that it works well in most cases and probably is the
best alternative on the "market". Anyway, I like to stay cross
platform for my projects so I personally develop on a Mac but mostly
deliver on win32.
Building works fine for me (using Makefile gen for mac and VS for win)
but I have huge problems with the bundling process. On the Mac I want
to deliver an app using regular drag and drop as a self contained
bundle and on windows I want to deliver an installer.
I have managed to get a win32 installer working using the NSIS
facilities but it took a lot of extra scripting. On the Mac I have
been able to create the dragndrop bundle "installer" but it doesn't
really work. I assume there are some issues with
rpath/loader_path/executable_path.
For reference the app is an Openscenegraph app that is dependant on
quite a few libraries that need to be bundled as dll:s on win and
dylibs/.so on mac.
The question is: what is the current "best practices approaches" on
these platforms? I have found no complete examples.
Finally: parts of my cmake test case for win32: THis works fine and
creates a usable app that bundles the osg libs as well as a plugin and
data. It just doesn't feel very neat for being user code.
#Basic app test (packaging exercise)
SET(TARGET_BASIC_APP_SRC BasicApp.cpp BasicAppMain.cpp)
ADD_EXECUTABLE(BasicApp ${TARGET_BASIC_APP_SRC} )
TARGET_LINK_LIBRARIES(BasicApp ${MY_COMMON_LIBS})
IF(WIN32 AND NOT UNIX)
SET(CPACK_GENERATOR "NSIS")
INSTALL(
TARGETS BasicApp
DESTINATION bin
)
SET(OSG_DLL_DIR $ENV{OSG_ROOT}\\bin)
FILE(TO_CMAKE_PATH ${OSG_DLL_DIR} OSG_DLL_DIR_CPATH)
SET(CMAKE_INSTALL_DEBUG_LIBRARIES)
INCLUDE(InstallRequiredSystemLibraries)
SET(CPACK_PACKAGE_EXECUTABLES "BasicApp" "Basic App")
CONFIGURE_FILE(
"${CMAKE_MODULE_PATH}/dependencies.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake"
@ONLY
)
INSTALL(CODE "set(input_file
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/BasicApp.exe \")")
INSTALL(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake")
SET(OSG_PLUGINS_DIR
"${OSG_DLL_DIR_CPATH}/osgPlugins-${OPENSCENEGRAPH_VERSION}")
MESSAGE("Installing plugins from: ${OSG_PLUGINS_DIR}")
# Extra plugin installs that the dependency checker can't find
INSTALL(
FILES "${OSG_PLUGINS_DIR}/osgdb_obj.dll"
DESTINATION bin)
# Install data that uses (at runtime) the plugin above
INSTALL(FILES
"${Dope_SOURCE_DIR}/data/models/clogo.obj"
"${Dope_SOURCE_DIR}/data/models/clogo.mtl"
DESTINATION data/models)
# Create shortcuts usin NSIS commands
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS " CreateShortCut
'$INSTDIR\\\\shortcut.lnk' '$INSTDIR\\\\bin\\\\BasicApp.exe' ")
# Install vc90 sp1 redist
# windows update broke a lot of things so lets add an vcdist
dependant installer
INSTALL(FILES
"${Dope_SOURCE_DIR}/external/win32_vc9/win_extras/vcredist_x86.exe"
DESTINATION win32_extras/)
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait
'$INSTDIR\\\\win32_extras\\\\vcredist_x86.exe'")
ENDIF(WIN32 AND NOT UNIX)
# dependcies.cmake.in is:
if(NOT DEFINED input_file)
message(FATAL_ERROR "input file is not defined")
endif(NOT DEFINED input_file)
message("Using ${input_file}")
INCLUDE(GetPrerequisites)
GET_PREREQUISITES(${input_file} DEPENDENCIES 1 1 "" "")
FOREACH(DEPENDENCY ${DEPENDENCIES})
MESSAGE("DEPENDENCY: ${DEPENDENCY}")
GET_FILENAME_COMPONENT(DEPENDENCY_NAME "${DEPENDENCY}" NAME)
GET_FILENAME_COMPONENT(DEPENDENCY_ACTUAL "${DEPENDENCY}" REALPATH)
MESSAGE("DEPENDENCY_NAME: ${DEPENDENCY_NAME}")
MESSAGE("DEPENDENCY_ACTUAL: ${DEPENDENCY_ACTUAL}")
FIND_FILE(${DEPENDENCY_NAME}_REAL_PATH ${DEPENDENCY_NAME} )
MESSAGE("DEPENDENCY_REAL_PATH: ${${DEPENDENCY_NAME}_REAL_PATH}")
MESSAGE("installing into: ${CMAKE_INSTALL_PREFIX}/bin")
FILE(COPY ${${DEPENDENCY_NAME}_REAL_PATH} DESTINATION
"${CMAKE_INSTALL_PREFIX}/bin")
#INSTALL(FILES "${DEPENDENCY_REAL_PATH}" DESTINATION bin)
ENDFOREACH()
On the mac, I don't have any working code yet. I feel that I am close,
but as it is, the code cannot load the right plugin
IF (APPLE)
SET(MACOSX_BUNDLE_INFO_STRING "MACOSX_BUNDLE_INFO_STRING")
SET(MACOSX_BUNDLE_ICON_FILE "")
SET(MACOSX_BUNDLE_GUI_IDENTIFIER "BasicAppGuiId")
SET(MACOSX_BUNDLE_LONG_VERSION_STRING "long ver string")
SET(MACOSX_BUNDLE_BUNDLE_NAME "BasicAPpBundleName")
SET(MACOSX_BUNDLE_SHORT_VERSION_STRING "short ver")
# setup the bundle
SET(BasicApp_BUNDLE_NAME "BasicApp")
SET_TARGET_PROPERTIES(BasicApp PROPERTIES OUTPUT_NAME
${BasicApp_BUNDLE_NAME})
SET(BasicApp_BUNDLE_LOCATION "${CMAKE_INSTALL_PREFIX}")
MESSAGE("ORIGINAL CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
# make sure CMAKE_INSTALL_PREFIX ends in /
STRING(LENGTH "${CMAKE_INSTALL_PREFIX}" LEN)
MATH(EXPR LEN "${LEN} -1" )
STRING(SUBSTRING "${CMAKE_INSTALL_PREFIX}" ${LEN} 1 ENDCH)
IF(NOT "${ENDCH}" STREQUAL "/")
SET(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/")
ENDIF(NOT "${ENDCH}" STREQUAL "/")
SET(CMAKE_INSTALL_PREFIX
"${CMAKE_INSTALL_PREFIX}${BasicApp_BUNDLE_NAME}.app/Contents")
MESSAGE("CHANGED CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
INSTALL(
TARGETS BasicApp
RUNTIME DESTINATION bin
BUNDLE DESTINATION "." )
INSTALL(FILES ${Dope_SOURCE_DIR}/ReadMe.txt DESTINATION "." )
SET(BasicAppFullPath "${CMAKE_INSTALL_PREFIX}/MacOS/${BasicApp_BUNDLE_NAME}")
MESSAGE("BasicAppFullPath: ${BasicAppFullPath}")
# INSTALL(CODE "set(input_file \"/MacOS/${BasicApp_BUNDLE_NAME}\")")
MESSAGE("INSTALL CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
INSTALL(CODE "set(lib_path \"/usr/local/lib\")")
INSTALL(CODE "set(input_file
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${BasicApp_BUNDLE_NAME}.app/Contents/MacOS/${BasicApp_BUNDLE_NAME}\")")
INSTALL(SCRIPT
"${Dope_SOURCE_DIR}/CMakeModules/CMakeIngestOSXBundleLibraries.cmake")
INSTALL(FILES
"${Dope_SOURCE_DIR}/data/models/clogo.obj"
"${Dope_SOURCE_DIR}/data/models/clogo.mtl"
DESTINATION
"./${BasicApp_BUNDLE_NAME}.app/Contents/Resources/data/models/")
MESSAGE("OSG VERSION: ${OPENSCENEGRAPH_VERSION}")
SET(OSG_PLUGINS_DIR
"/usr/local/lib/osgPlugins-${OPENSCENEGRAPH_VERSION}")
INSTALL(FILES
"${OSG_PLUGINS_DIR}/osgdb_obj.so"
DESTINATION
"./${BasicApp_BUNDLE_NAME}.app/Contents/PlugIns/osgPlugins-${OPENSCENEGRAPH_VERSION}/")
SET(CPACK_GENERATOR "DragNDrop")
ENDIF(APPLE)
I tried to use code from the cmake 2.8 qt dialog working example
(among other things, the CMakeIngestOSXBundleLibraries.cmake comes
from there)
Ok, first post over :)
/Filip
More information about the CMake
mailing list