Skip to content
55 changes: 49 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,25 @@ 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()
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)
Expand Down Expand Up @@ -332,6 +351,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()
Expand All @@ -341,8 +363,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)
Expand All @@ -358,6 +387,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})
Expand All @@ -384,6 +417,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 $<TARGET_FILE_DIR:python>/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.
Expand Down Expand Up @@ -454,7 +490,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
Expand Down Expand Up @@ -569,7 +609,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()

Expand All @@ -579,9 +619,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 $<TARGET_FILE_DIR:python>/Makefile
INPUT ${BIN_BUILD_DIR}/Makefile.in)
if(INSTALL_DEVELOPMENT)
install(FILES ${BIN_BUILD_DIR}/Makefile
install(FILES $<TARGET_FILE_DIR:python>/Makefile
DESTINATION ${LIB_CONFIG_INSTALL_DIR}
RENAME Makefile
COMPONENT Development)
Expand All @@ -596,7 +639,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()
Expand Down
4 changes: 3 additions & 1 deletion cmake/ConfigureChecks.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
18 changes: 18 additions & 0 deletions cmake/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
4 changes: 4 additions & 0 deletions cmake/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}")
Expand Down
18 changes: 17 additions & 1 deletion cmake/libpython/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -491,11 +490,28 @@ 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 ${FRAMEWORK_NAME}
)
else()
set_target_properties(${name} PROPERTIES
INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/${LIBPYTHON_LIBDIR}
)
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()
Expand Down
10 changes: 5 additions & 5 deletions cmake/makefile-variables.in
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 7 additions & 1 deletion cmake/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -59,7 +65,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} $<TARGET_FILE:python> -E -S -m sysconfig --generate-posix-vars
${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:python> -S -m sysconfig --generate-posix-vars
COMMAND ${CMAKE_COMMAND}
-DBIN_BUILD_DIR:PATH=${BIN_BUILD_DIR}
-DSYSCONFIGDATA_PY:STRING=${_sysconfigdata_py}
Expand Down