MakePythonWheel.cmake 6.18 KiB
# This function makes a Python distribution wheel for the given version of Python platform.
include("multipython/PyDirectories") # set_python_package_dirs
function(make_python_wheel)
# parse function arguments for text like 'PYTAG xy',
# and set local variable '__PYTAG' to 'xy'.
cmake_parse_arguments("_" "" "Py3_EXECUTABLE;Py3_VERSION" "Py3_INCLUDE_DIRS;Py3_LIBRARY_DIRS" ${ARGN})
set(header "Python wheel (${__Py3_VERSION}):")
# make directories for the Python wheel
set_python_package_dirs(${__Py3_VERSION})
#-- define the main target to build a Python wheel
# store the external libraries needed for making the Python wheel
if(WIN32)
set(_extra_libs "${BA_Dependencies_WIN32}")
else()
set(_extra_libs "${BA_Dependencies}")
endif()
# make the Python wheel
if(APPLE)
# On MacOS, building the Python packages needs further effort
# which is performed in a dedicated shell script which
# should be executed after build process is done (like CPack).
set(BA_PY_MODE "ON")
set(MACPKG_EXTRA_LIBS "${_extra_libs}")
configure_file("${CMAKE_SOURCE_DIR}/devtools/deploy/mac/mac_package.py.in"
${BUILD_VAR_DIR}/mac_py_package.py @ONLY)
add_custom_target(BAPyWheel ALL
COMMENT "${header} Script to build the Python wheel: "
"'${${BUILD_VAR_DIR}/mk_pypack_macos.zsh}'"
)
elseif(LINUX)
# On Linux, building the Python packages needs further effort
# which is performed in a dedicated shell script which
# should be executed after build process is done (like CPack).
configure_file("${CMAKE_SOURCE_DIR}/devtools/deploy/linux/mk_pypack_linux.sh.in"
${BUILD_VAR_DIR}/mk_pypack_linux.sh @ONLY)
add_custom_target(BAPyWheel ALL
COMMENT "${header} Script to build the Python wheel: "
"'${${BUILD_VAR_DIR}/mk_pypack_linux.sh}'"
)
else()
# MS-Windows
add_custom_target(BAPyWheel ALL
COMMAND ${__Py3_EXECUTABLE} -m pip wheel ${BA_PY_OUTPUT_DIR} --no-deps --wheel ${BA_PY_PACKAGE_WHEEL_DIR}
COMMENT "${header} Making the Python wheel..."
)
endif()
set_target_properties(BAPyWheel PROPERTIES
_EXTRA_LIBRARIES "${_extra_libs}")
#-- store the configuration files for the Python package
# make the version-dependent setup config
set(_setup_cfg ${BA_PY_OUTPUT_DIR}/setup.cfg)
set(BA_PY_VERSION_MAJOR ${BornAgain_VERSION_MAJOR})
set(BA_PY_VERSION_MINOR ${BornAgain_VERSION_MINOR})
set(_setup_py ${BA_PY_OUTPUT_DIR}/setup.py)
set(BA_PY_PACKAGE_C_EXT "src/bornagain_c_ext_dummy.c")
set(BA_PY_PACKAGE_C_EXT_INC_DIRS "${__Py3_INCLUDE_DIRS}")
set(BA_PY_PACKAGE_C_EXT_LIB_DIRS "${__Py3_LIBRARY_DIRS}")
configure_file(${BA_PY_PACKAGE_ROOT_DIR}/setup.cfg.in
${_setup_cfg} @ONLY)
configure_file(${BA_PY_PACKAGE_ROOT_DIR}/setup.py.in
${_setup_py} @ONLY)
# copy config files
set(_dst ${BA_PY_OUTPUT_DIR}/)
file(GLOB _config_files
${BA_PY_PACKAGE_ROOT_DIR}/pyproject.toml
${BA_PY_PACKAGE_ROOT_DIR}/MANIFEST.in
)
add_custom_target(BAPyWheel_config_files
COMMAND ${CMAKE_COMMAND} -E copy ${_config_files} ${_dst}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/README.md ${_dst}/
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/COPYING ${_dst}/
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/CITATION ${_dst}/
COMMENT "${header} Copying config files to '${_dst}'..."
DEPENDS ${_setup_cfg} ${_setup_py}
)
# store dummy C extension for the Python package
# NOTE: Dummy C extension is used merely to set the correct wheel tag
# according to PEP 425
set(_dst ${BA_PY_SOURCE_OUTPUT_DIR})
file(GLOB _c_dummy_file ${BA_PY_PACKAGE_ROOT_DIR}/${BA_PY_PACKAGE_C_EXT})
add_custom_target(BAPyWheel_c_dummy_file
COMMAND ${CMAKE_COMMAND} -E copy ${_c_dummy_file} ${_dst}
COMMENT "${header} Copying dummy C extension file to '${_dst}'..."
)
# store init files for the Python package
set(_dst ${BA_PY_INIT_OUTPUT_DIR}/)
set(_dst_lib ${BA_PY_LIBRARY_OUTPUT_DIR}/)
file(GLOB _ba_py_files ${BA_PY_PACKAGE_ROOT_DIR}/src/bornagain/*.py)
file(GLOB _init_files_lib ${BA_PY_PACKAGE_ROOT_DIR}/src/bornagain/lib/*.py)
configure_file(${BA_PY_PACKAGE_ROOT_DIR}/src/bornagain/__init__.py.in
${_dst}/__init__.py @ONLY)
add_custom_target(BAPyWheel_init_files
COMMAND ${CMAKE_COMMAND} -E copy ${_ba_py_files} ${_dst}
COMMAND ${CMAKE_COMMAND} -E copy ${_init_files_lib} ${_dst_lib}
COMMENT "${header} Copying init files to '${_dst}'..."
)
# store the required extra libraries
set(_dst ${BA_PY_EXTRA_LIBRARY_OUTPUT_DIR})
add_custom_target(BAPyWheel_extra_libs
COMMAND ${CMAKE_COMMAND} -E copy ${_extra_libs} ${_dst}
COMMENT "${header} Copying extra libraries {${_extra_libs}} to '${_dst}'..."
)
# add dependencies
add_dependencies(BAPyWheel
BAPyWheel_config_files
BAPyWheel_c_dummy_file
BAPyWheel_init_files
BAPyWheel_extra_libs
)
endfunction()
function(add_library_to_wheel lib)
# add_library_to_wheel: Add a BornAgain library to the Python wheel
# NOTE: Target BAPyWheel must be already defined.
add_dependencies(BAPyWheel ${lib})
# eg., 'libBornAgain.so'
get_target_property(libfilename ${lib} _BASEFILENAME)
# copy the shared library and its Python interface to the Python wheel folder
set(_dst ${BA_PY_LIBRARY_OUTPUT_DIR}/)
add_custom_command(TARGET ${lib}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:${lib}>" ${_dst}/${libfilename}
COMMENT "Add library ${lib} to the Python wheel..."
)
get_target_property(lib_LIBRARY_PY ${lib} _LIBRARY_PY)
string(STRIP ${lib_LIBRARY_PY} lib_LIBRARY_PY)
if(lib_LIBRARY_PY)
add_custom_command(TARGET ${lib}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_PROPERTY:${lib},_LIBRARY_PY>" ${_dst}
COMMENT "Add Python wrapper-script of library ${lib} to the Python wheel..."
)
endif()
endfunction()