Skip to content

MacOSX: Support building of a Python.framework #169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
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