From a7dee01711bc2f61f8055d68d41cb983034c919b Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Sat, 9 Apr 2016 20:16:24 +0200 Subject: [PATCH 1/8] Add Mac OSX framework support --- CMakeLists.txt | 8 ++++++++ cmake/libpython/CMakeLists.txt | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c451e4ee9..47197a3e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,14 @@ else() set(BUILD_WININST OFF) set(BUILD_WININST_ALWAYS OFF) endif() +if(APPLE) + option(BUILD_FRAMEWORK "Build a Mac OSX Framework" OFF) + if(BUILD_FRAMEWORK) + set(BUILD_LIBPYTHON_SHARED ON CACHE BOOL "Forced to ON because of BUILD_FRAMEWORK=ON" FORCE) + endif() +else() + set(BUILD_FRAMEWORK OFF) +endif() option(INSTALL_DEVELOPMENT "Install files required to develop C extensions" ON) option(INSTALL_MANUAL "Install man files" ON) option(INSTALL_TEST "Install test files" ON) diff --git a/cmake/libpython/CMakeLists.txt b/cmake/libpython/CMakeLists.txt index 6b183b287..c6476815c 100644 --- a/cmake/libpython/CMakeLists.txt +++ b/cmake/libpython/CMakeLists.txt @@ -491,11 +491,24 @@ function(add_libpython name type install component) # Export target set_property(GLOBAL APPEND PROPERTY PYTHON_TARGETS ${name}) + if(BUILD_FRAMEWORK) + set_target_properties(${name} PROPERTIES + FRAMEWORK TRUE + FRAMEWORK_VERSION "${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}" + MACOSX_FRAMEWORK_IDENTIFIER org.python.python + MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}" + MACOSX_FRAMEWORK_BUNDLE_VERSION "${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}" + MACOSX_RPATH ON + OUTPUT_NAME Python + ) + endif() + if(install) install(TARGETS ${name} EXPORT PythonTargets ARCHIVE DESTINATION ${LIBPYTHON_ARCHIVEDIR} LIBRARY DESTINATION ${LIBPYTHON_LIBDIR} RUNTIME DESTINATION ${LIBPYTHON_LIBDIR} + FRAMEWORK DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT ${component} ) endif() From 8f26d60e3e01771e474a178a0b3d3edbffc98ebd Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Sat, 17 Sep 2016 21:36:45 +0200 Subject: [PATCH 2/8] Install binaries, libraries, headers files and auxilliary files into framework --- CMakeLists.txt | 22 +++++++++++++++++++--- cmake/include/CMakeLists.txt | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47197a3e8..6e4cb0e5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,8 @@ if(APPLE) if(BUILD_FRAMEWORK) set(BUILD_LIBPYTHON_SHARED ON CACHE BOOL "Forced to ON because of BUILD_FRAMEWORK=ON" FORCE) endif() + set(FRAMEWORK_DIR_ROOT Python.framework) + set(FRAMEWORK_DIR_PREFIX ${FRAMEWORK_DIR_ROOT}/Versions/${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}) else() set(BUILD_FRAMEWORK OFF) endif() @@ -340,6 +342,9 @@ if(USE_LIB64) set(LIBDIR "lib64") endif() set(PYTHONHOME "${LIBDIR}") +if(BUILD_FRAMEWORK) + set(LIBDIR ${FRAMEWORK_DIR_PREFIX}/lib) +endif() if(UNIX) set(PYTHONHOME "${PYTHONHOME}/${LIBPYTHON}") endif() @@ -349,8 +354,15 @@ set(BIN_INSTALL_DIR bin) # Contains the python executabl if(INSTALL_WINDOWS_TRADITIONAL) set(BIN_INSTALL_DIR .) # Contains the python executable endif() +if(BUILD_FRAMEWORK) + set(BIN_INSTALL_DIR ${FRAMEWORK_DIR_PREFIX}/bin) +endif() +set(SHARE_INSTALL_DIR share) +if(BUILD_FRAMEWORK) + set(SHARE_INSTALL_DIR ${FRAMEWORK_DIR_PREFIX}/share) +endif() set(LD_VERSION ${LIBPYTHON_VERSION}${ABIFLAGS}) -set(CONFIG_INSTALL_DIR share/${LIBPYTHON}) +set(CONFIG_INSTALL_DIR ${SHARE_INSTALL_DIR}/${LIBPYTHON}) set(EXTENSION_INSTALL_DIR ${PYTHONHOME}/lib-dynload) if (${LIBPYTHON_VERSION} GREATER 3.1) @@ -366,6 +378,10 @@ set(INCLUDE_INSTALL_DIR include/python${LD_VERSION}) if(MSVC) set(INCLUDE_INSTALL_DIR include) endif() +if(BUILD_FRAMEWORK) + set(REL_INCLUDE_INSTALL_DIR include/python${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}) + set(INCLUDE_INSTALL_DIR ${FRAMEWORK_DIR_PREFIX}/include/python${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}) +endif() # Build tree directory set(BIN_BUILD_DIR ${PROJECT_BINARY_DIR}/bin) set(CONFIG_BUILD_DIR ${PROJECT_BINARY_DIR}/${CONFIG_INSTALL_DIR}) @@ -577,7 +593,7 @@ if(UNIX) ${PROJECT_BINARY_DIR}/Misc/python-${LIBPYTHON_VERSION}.pc ${PROJECT_BINARY_DIR}/Misc/python-${PY_VERSION_MAJOR}.pc ${PROJECT_BINARY_DIR}/Misc/python.pc - DESTINATION lib/pkgconfig + DESTINATION ${LIBDIR}/pkgconfig COMPONENT Development) endif() @@ -604,7 +620,7 @@ if(UNIX) # Install manual if(INSTALL_MANUAL) - set(_install_man FILES ${SRC_DIR}/Misc/python.man DESTINATION share/man/man1 COMPONENT Runtime) + set(_install_man FILES ${SRC_DIR}/Misc/python.man DESTINATION ${SHARE_INSTALL_DIR}/man/man1 COMPONENT Runtime) install(${_install_man} RENAME python${LIBPYTHON_VERSION}.1) install(${_install_man} RENAME python${PY_VERSION_MAJOR}.1) endif() diff --git a/cmake/include/CMakeLists.txt b/cmake/include/CMakeLists.txt index f75ede6e1..e14bb19f3 100644 --- a/cmake/include/CMakeLists.txt +++ b/cmake/include/CMakeLists.txt @@ -12,3 +12,21 @@ foreach(file ${hfiles}) install(FILES ${includedir}/${file} DESTINATION ${INCLUDE_INSTALL_DIR}/${path} COMPONENT Development) endif() endforeach() +if(BUILD_FRAMEWORK) + install(CODE " + message(STATUS \"Creating Python header framework symlinks...\") + execute_process( + COMMAND + \${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers Headers + WORKING_DIRECTORY + \"${CMAKE_INSTALL_PREFIX}/${FRAMEWORK_DIR_ROOT}\" + ) + + execute_process( + COMMAND + \${CMAKE_COMMAND} -E create_symlink \"${REL_INCLUDE_INSTALL_DIR}\" Headers + WORKING_DIRECTORY + \"${CMAKE_INSTALL_PREFIX}/${FRAMEWORK_DIR_PREFIX}\" + ) + ") +endif() From 5bda756af4152ac81a902ef059a0ece5da918ad4 Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Sun, 18 Sep 2016 23:18:14 +0200 Subject: [PATCH 3/8] Change PYTHONPATH and PYTHONHOME for framework builds --- CMakeLists.txt | 6 +++++- cmake/ConfigureChecks.cmake | 4 +++- cmake/python/CMakeLists.txt | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e4cb0e5e..f5eeccd9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -478,7 +478,11 @@ if(BUILD_LIBPYTHON_SHARED AND UNIX) if(APPLE) set(_envvar DYLD_LIBRARY_PATH) endif() - set(PYTHON_WRAPPER_COMMAND env ${_envvar}=${PROJECT_BINARY_DIR}/${LIBPYTHON_LIBDIR}) + set(PYTHON_HOME_PATH ) + if(BUILD_FRAMEWORK) + set(PYTHON_HOME_PATH PYTHONHOME=${PROJECT_BINARY_DIR}/${PYTHONHOME} PYTHONPATH=${PROJECT_BINARY_DIR}/${PYTHONHOME}) + endif() + set(PYTHON_WRAPPER_COMMAND env ${_envvar}=${PROJECT_BINARY_DIR}/${LIBPYTHON_LIBDIR} ${PYTHON_HOME_PATH}) endif() # Add extension modules diff --git a/cmake/ConfigureChecks.cmake b/cmake/ConfigureChecks.cmake index 92e98aa00..10e65469e 100644 --- a/cmake/ConfigureChecks.cmake +++ b/cmake/ConfigureChecks.cmake @@ -645,7 +645,9 @@ set(WITH_DYLD 0) set(WITH_NEXT_FRAMEWORK 0) if(APPLE) set(WITH_DYLD 1) - set(WITH_NEXT_FRAMEWORK 0) # TODO: See --enable-framework option. + if(BUILD_FRAMEWORK) + set(WITH_NEXT_FRAMEWORK 1) # TODO: See --enable-framework option. + endif() endif() if(HAVE_LONG_LONG) diff --git a/cmake/python/CMakeLists.txt b/cmake/python/CMakeLists.txt index cdb291e39..90e4abe63 100644 --- a/cmake/python/CMakeLists.txt +++ b/cmake/python/CMakeLists.txt @@ -59,7 +59,7 @@ if(UNIX AND PY_VERSION VERSION_GREATER "2.7.4") add_custom_command( OUTPUT ${BIN_BUILD_DIR}/pybuilddir.txt ${EXTENSION_BUILD_DIR}/${_sysconfigdata_py} COMMAND ${PYTHON_WRAPPER_COMMAND} - ${CMAKE_CROSSCOMPILING_EMULATOR} $ -E -S -m sysconfig --generate-posix-vars + ${CMAKE_CROSSCOMPILING_EMULATOR} $ -S -m sysconfig --generate-posix-vars COMMAND ${CMAKE_COMMAND} -DBIN_BUILD_DIR:PATH=${BIN_BUILD_DIR} -DSYSCONFIGDATA_PY:STRING=${_sysconfigdata_py} From f52f1dc908faffa68ab3618917be7b56a2864df7 Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Tue, 20 Sep 2016 17:21:09 +0200 Subject: [PATCH 4/8] Install platform library files on MacOSX --- cmake/lib/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/lib/CMakeLists.txt b/cmake/lib/CMakeLists.txt index 82e8ec89c..31d18ebe1 100644 --- a/cmake/lib/CMakeLists.txt +++ b/cmake/lib/CMakeLists.txt @@ -7,6 +7,10 @@ if(UNIX) set(plat_subdir "plat-linux2") endif() +if(APPLE) + set(plat_subdir "plat-darwin") +endif() + foreach(file ${libfiles}) # Don't install files for other platforms string(REGEX MATCH "^plat-" is_platform_file "${file}") From a183814994fd65ec18b7e9ba9dbdca506083cfd2 Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Thu, 29 Sep 2016 22:36:31 +0200 Subject: [PATCH 5/8] Install configure Makefile and pyconfig.h for sysconfig into INT dir This is required when using multi-config cmake generators. --- CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5eeccd9d..5bed4ed6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -408,6 +408,9 @@ if(UNIX) set(PYCONFIG_BUILD_DIR ${BIN_BUILD_DIR}) configure_file(cmake/config-unix/pyconfig.h.in ${PYCONFIG_BUILD_DIR}/pyconfig.h) + file(GENERATE + OUTPUT $/pyconfig.h + INPUT ${PYCONFIG_BUILD_DIR}/pyconfig.h) elseif(WIN32) set(PYCONFIG_BUILD_DIR ${SRC_DIR}/PC) # In a windows build tree, 'pyconfig.h' is NOT required to # live along side the python executable. @@ -607,9 +610,12 @@ if(UNIX) set(MAKEFILE_LDSHARED_FLAGS "-dynamiclib -headerpad_max_install_names -undefined dynamic_lookup") endif() configure_file(cmake/makefile-variables.in - ${BIN_BUILD_DIR}/Makefile @ONLY) + ${BIN_BUILD_DIR}/Makefile.in @ONLY) + file(GENERATE + OUTPUT $/Makefile + INPUT ${BIN_BUILD_DIR}/Makefile.in) if(INSTALL_DEVELOPMENT) - install(FILES ${BIN_BUILD_DIR}/Makefile + install(FILES $/Makefile DESTINATION ${LIB_CONFIG_INSTALL_DIR} RENAME Makefile COMPONENT Development) From 9adfa872819ac846c2a7246862290f18807f09eb Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Wed, 19 Oct 2016 12:09:42 +0200 Subject: [PATCH 6/8] Populate Makefile variable with MacOSX framework variables --- CMakeLists.txt | 13 +++++++++++-- cmake/libpython/CMakeLists.txt | 2 +- cmake/makefile-variables.in | 10 +++++----- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bed4ed6d..3c91a4186 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,11 +84,20 @@ if(APPLE) if(BUILD_FRAMEWORK) set(BUILD_LIBPYTHON_SHARED ON CACHE BOOL "Forced to ON because of BUILD_FRAMEWORK=ON" FORCE) endif() - set(FRAMEWORK_DIR_ROOT Python.framework) - set(FRAMEWORK_DIR_PREFIX ${FRAMEWORK_DIR_ROOT}/Versions/${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}) else() set(BUILD_FRAMEWORK OFF) endif() +if(BUILD_FRAMEWORK) + set(FRAMEWORK_NAME Python) + set(FRAMEWORK_PREFIX ${CMAKE_INSTALL_PREFIX}) + set(FRAMEWORK_DIR_ROOT ${FRAMEWORK_NAME}.framework) + set(FRAMEWORK_DIR_PREFIX ${FRAMEWORK_DIR_ROOT}/Versions/${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}) +else() + set(FRAMEWORK_NAME "") + set(FRAMEWORK_PREFIX "") + set(FRAMEWORK_DIR_ROOT "no-framework") + set(FRAMEWORK_DIR_PREFIX "") +endif() option(INSTALL_DEVELOPMENT "Install files required to develop C extensions" ON) option(INSTALL_MANUAL "Install man files" ON) option(INSTALL_TEST "Install test files" ON) diff --git a/cmake/libpython/CMakeLists.txt b/cmake/libpython/CMakeLists.txt index c6476815c..0abf9df53 100644 --- a/cmake/libpython/CMakeLists.txt +++ b/cmake/libpython/CMakeLists.txt @@ -499,7 +499,7 @@ function(add_libpython name type install component) MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}" MACOSX_FRAMEWORK_BUNDLE_VERSION "${PY_VERSION_MAJOR}.${PY_VERSION_MINOR}" MACOSX_RPATH ON - OUTPUT_NAME Python + OUTPUT_NAME ${FRAMEWORK_NAME} ) endif() diff --git a/cmake/makefile-variables.in b/cmake/makefile-variables.in index 5dd942cbb..a899a7cbe 100644 --- a/cmake/makefile-variables.in +++ b/cmake/makefile-variables.in @@ -103,11 +103,11 @@ EXE= @CMAKE_EXECUTABLE_SUFFIX@ BUILDEXE= @CMAKE_EXECUTABLE_SUFFIX@ # Short name and location for Mac OS X Python framework -UNIVERSALSDK= -PYTHONFRAMEWORK= -PYTHONFRAMEWORKDIR= no-framework -PYTHONFRAMEWORKPREFIX= -PYTHONFRAMEWORKINSTALLDIR= +UNIVERSALSDK= @CMAKE_OSX_SYSROOT@ +PYTHONFRAMEWORK= @FRAMEWORK_NAME@ +PYTHONFRAMEWORKDIR= @FRAMEWORK_DIR_ROOT@ +PYTHONFRAMEWORKPREFIX= @FRAMEWORK_PREFIX@ +PYTHONFRAMEWORKINSTALLDIR= @FRAMEWORK_DIR_PREFIX@ # Deployment target selected during configure, to be checked # by distutils. The export statement is needed to ensure that the # deployment target is active during build. From 20bc0ccef699ef123f5d6672023d67e48ac7ee60 Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Tue, 15 Nov 2016 10:57:52 +0100 Subject: [PATCH 7/8] Set INSTALL_NAME_DIR only for non-frameworks on OSX --- cmake/libpython/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/libpython/CMakeLists.txt b/cmake/libpython/CMakeLists.txt index 0abf9df53..5f9b7961f 100644 --- a/cmake/libpython/CMakeLists.txt +++ b/cmake/libpython/CMakeLists.txt @@ -480,7 +480,6 @@ function(add_libpython name type install component) OUTPUT_NAME ${LIBPYTHON}${ABIFLAGS} LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${LIBPYTHON_LIBDIR} RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${LIBPYTHON_LIBDIR} - INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/${LIBPYTHON_LIBDIR} ) if(HAVE_POSITION_INDEPENDENT_CODE) set_target_properties(${name} PROPERTIES @@ -501,6 +500,10 @@ function(add_libpython name type install component) MACOSX_RPATH ON OUTPUT_NAME ${FRAMEWORK_NAME} ) + else() + set_target_properties(${name} PROPERTIES + INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/${LIBPYTHON_LIBDIR} + ) endif() if(install) From d5adfa4bbb85a245d17eb952310307f3f08ae959 Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Thu, 1 Dec 2016 12:41:06 +0100 Subject: [PATCH 8/8] Set python exe RPATH to search for libpython in Frameworks --- cmake/python/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/python/CMakeLists.txt b/cmake/python/CMakeLists.txt index 90e4abe63..48f3a0f74 100644 --- a/cmake/python/CMakeLists.txt +++ b/cmake/python/CMakeLists.txt @@ -27,6 +27,12 @@ if(MSVC) set_target_properties(python PROPERTIES LINK_FLAGS /STACK:2000000) endif() +if(BUILD_FRAMEWORK) + set_target_properties(python PROPERTIES + INSTALL_RPATH "@rpath/.."; + ) +endif() + # Export target set_property(GLOBAL APPEND PROPERTY PYTHON_TARGETS python)