From e09db44906022fdb208fe1fff915864ed476d55a Mon Sep 17 00:00:00 2001 From: Marco Antognini Date: Sat, 20 Aug 2011 12:14:55 +0200 Subject: [PATCH] Cmake now is able to build SFML libraries as frameworks (closes #12) Cmake can now automatically install the Xcode templates --- CMakeLists.txt | 101 +++++++++++++++++++++++++++++------ cmake/Macros.cmake | 29 +++++++--- cmake/Modules/FindSFML.cmake | 7 ++- 3 files changed, 113 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2496cb9bd..9cfe2e691 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,9 +31,20 @@ set(BUILD_EXAMPLES FALSE CACHE BOOL "TRUE to build the SFML examples, FALSE to i set(BUILD_DOC FALSE CACHE BOOL "TRUE to generate the API documentation, FALSE to ignore it") # Mac OS X specific options -if (MACOSX AND MACOSX_VERSION GREATER 5) - # add an option to build against 10.5 SDK if current OS X version is greater than 10.5 - set(BUILD_LEOPARD FALSE CACHE BOOL "TRUE to build SFML for OS X 10.5, FALSE to compile with default SDK") +if(MACOSX) + if(MACOSX_VERSION GREATER 5) + # add an option to build against 10.5 SDK if current OS X version is greater than 10.5 + set(BUILD_LEOPARD FALSE CACHE BOOL "TRUE to build SFML for OS X 10.5, FALSE to compile with default SDK") + endif() + + # add an option to build frameworks instead of dylibs (release only) + set(BUILD_FRAMEWORKS FALSE CACHE BOOL "TRUE to build SFML as frameworks libraries (release only), FALSE to build according to BUILD_SHARED_LIBS") + + # add an option to let the user specify a custom directory for frameworks installation (SFML, sndfile, ...) + set(CMAKE_INSTALL_FRAMEWORK_PREFIX "/Library/Frameworks" CACHE STRING "Frameworks installation directory") + + # add an option to automatically install Xcode 4 templates + set(INSTALL_XCODE4_TEMPLATES FALSE CACHE BOOL "TRUE to automatically install the Xcode 4 templates, FALSE to do nothing about it") endif() # define SFML_STATIC if the build type is not set to 'shared' @@ -65,9 +76,10 @@ endif() # disable the rpath stuff set(CMAKE_SKIP_BUILD_RPATH TRUE) -# Setup Mac OS X multi arch/SDK support. -if (MACOSX) - if (NOT CMAKE_OSX_ARCHITECTURES) +# Setup Mac OS X stuff +if(MACOSX) + # multi arch support + if(NOT CMAKE_OSX_ARCHITECTURES) # Default : i386 and x86_64 set(CMAKE_OSX_ARCHITECTURES "i386;x86_64") else() @@ -76,13 +88,31 @@ if (MACOSX) message("You're on your own : I won't change your settings.") endif() - # use 10.5 SDK ? - if (BUILD_LEOPARD) + # multi SDK support + if(BUILD_LEOPARD) # Use 10.5 SDK : override default value set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.5.sdk") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.5") else() # Default SDK, let either the user or CMake decide which one to use. + endif() + + # BUILD_FRAMEWORKS needs two things : + # first, it's available only for release + # (because cmake currently doesn't allow specifying a custom framework name so XXX-d is not possible) + # secondly, it works only with BUILD_SHARED_LIBS enabled + if(BUILD_FRAMEWORKS) + # requirement #1 + if(NOT CMAKE_BUILD_TYPE STREQUAL "Release") + message(WARNING "CMAKE_BUILD_TYPE should be \"Release\" when BUILD_FRAMEWORKS is TRUE") + return() + endif() + + # requirement #2 + if(NOT BUILD_SHARED_LIBS) + message(WARNING "BUILD_SHARED_LIBS should be TRUE when BUILD_FRAMEWORKS is TRUE") + return() + endif() endif() endif() @@ -95,13 +125,50 @@ if(BUILD_DOC) add_subdirectory(doc) endif() -# setup the install rules -install(DIRECTORY include - DESTINATION . - COMPONENT devel - PATTERN ".svn" EXCLUDE) +# setup the install rules +if(NOT BUILD_FRAMEWORKS) + install(DIRECTORY include + DESTINATION . + COMPONENT devel + PATTERN ".svn" EXCLUDE) +else() + # find only "root" headers + file(GLOB SFML_HEADERS RELATIVE ${PROJECT_SOURCE_DIR} "include/SFML/*") + + # in fact we have to fool cmake to copy all the headers in subdirectories + # to do that we have to add the "root" headers to the PUBLIC_HEADER + # then we can run a post script to copy the remaining headers + + # we need a dummy file in order to compile the framework + set(SFML_SOURCES ${SFML_HEADERS}) + list(APPEND SFML_SOURCES dummy.cpp) + + # create SFML.framework + add_library(SFML ${SFML_SOURCES}) + + # edit target properties + set_target_properties(SFML PROPERTIES + FRAMEWORK TRUE + FRAMEWORK_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} + MACOSX_FRAMEWORK_IDENTIFIER org.sfml-dev.SFML + MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} + MACOSX_FRAMEWORK_BUNDLE_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} + PUBLIC_HEADER "${SFML_HEADERS}") + + # add the remaining headers + add_custom_command(TARGET SFML + POST_BUILD + COMMAND cp -r ${PROJECT_SOURCE_DIR}/include/SFML/* SFML.framework/Versions/2.0.0/Headers) + + # install rule + install(TARGETS SFML + FRAMEWORK DESTINATION ${CMAKE_INSTALL_FRAMEWORK_PREFIX} + COMPONENT devel) +endif() + install(FILES cmake/Modules/FindSFML.cmake DESTINATION ${CMAKE_ROOT}/Modules) -install(FILES license.txt DESTINATION ${INSTALL_MISC_DIR}) +install(FILES license.txt DESTINATION ${INSTALL_MISC_DIR}) + if(WINDOWS) if(ARCH_32BITS) install(FILES extlibs/bin/x86/libsndfile-1.dll DESTINATION bin) @@ -111,5 +178,9 @@ if(WINDOWS) install(FILES extlibs/bin/x64/openal32.dll DESTINATION bin) endif() elseif(MACOSX) - install(DIRECTORY extlibs/libs-osx/Frameworks/sndfile.framework DESTINATION /Library/Frameworks PATTERN ".svn" EXCLUDE) + install(DIRECTORY extlibs/libs-osx/Frameworks/sndfile.framework DESTINATION ${CMAKE_INSTALL_FRAMEWORK_PREFIX}) + + if(INSTALL_XCODE4_TEMPLATES) + install(DIRECTORY xcode/templates/SFML DESTINATION $ENV{HOME}/Library/Developer/Xcode/Templates) + endif() endif() diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake index d94f4b070..0488f5249 100644 --- a/cmake/Macros.cmake +++ b/cmake/Macros.cmake @@ -138,17 +138,29 @@ macro(sfml_add_library target) target_link_libraries(${target} ${THIS_DEPENDS}) endif() + # build frameworks or dylibs + if(MACOSX AND BUILD_SHARED_LIBS) + if(BUILD_FRAMEWORKS) + # adapt target to build frameworks instead of dylibs + set_target_properties(${target} PROPERTIES + FRAMEWORK TRUE + FRAMEWORK_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} + MACOSX_FRAMEWORK_IDENTIFIER org.sfml-dev.${target} + MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} + MACOSX_FRAMEWORK_BUNDLE_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) + else() + # adapt install directory to allow distributing dylibs in user’s frameworks + set_target_properties(${target} PROPERTIES + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_NAME_DIR "@executable_path/../Frameworks") + endif() + endif() + # link the target to its external dependencies if(THIS_EXTERNAL_LIBS) if(BUILD_SHARED_LIBS) # in shared build, we use the regular linker commands - target_link_libraries(${target} ${THIS_EXTERNAL_LIBS}) - - if (MACOSX) - set_target_properties(${target} PROPERTIES - BUILD_WITH_INSTALL_RPATH 1 - INSTALL_NAME_DIR "@executable_path/../Frameworks") - endif() + target_link_libraries(${target} ${THIS_EXTERNAL_LIBS}) else() # in static build there's no link stage, but with some compilers it is possible to force # the generated static library to directly contain the symbols from its dependencies @@ -160,7 +172,8 @@ macro(sfml_add_library target) install(TARGETS ${target} RUNTIME DESTINATION bin COMPONENT bin LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT bin - ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT devel) + ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT devel + FRAMEWORK DESTINATION ${CMAKE_INSTALL_FRAMEWORK_PREFIX} COMPONENT bin) endmacro() diff --git a/cmake/Modules/FindSFML.cmake b/cmake/Modules/FindSFML.cmake index dac0132ff..5e4f727bf 100644 --- a/cmake/Modules/FindSFML.cmake +++ b/cmake/Modules/FindSFML.cmake @@ -11,7 +11,12 @@ # - SFML_INCLUDE_DIR, the path where SFML headers are located (the directory containing the SFML/Config.hpp file) # # By default, the dynamic libraries of SFML will be found. To find the static ones instead, -# you must set the SFML_STATIC_LIBRARIES variable to TRUE before calling find_package(SFML ...). +# you must set the SFML_STATIC_LIBRARIES variable to TRUE before calling find_package(SFML ...). +# +# On Mac OS X if SFML_STATIC_LIBRARIES is not set to TRUE then by default CMake will search for frameworks unless +# CMAKE_FIND_FRAMEWORK is set to "NEVER" for example. Please refer to CMake documentation for more details. +# Moreover, keep in mind that SFML frameworks are only available as release libraries unlike dylibs which +# are available for both release and debug modes. # # If SFML is not installed in a standard path, you can use the SFMLDIR CMake variable or environment variable # to tell CMake where SFML is.