Techt3o's picture
4f12b484f180574c6eb9e28ac739e76d44c165853db056d7b668b65be58331d0
739258a verified
raw
history blame
4.44 kB
# Useful references:
# https://thomastrapp.com/blog/building-a-pypi-package-for-a-modern-cpp-project/ for reference
# https://www.benjack.io/2017/06/12/python-cpp-tests.html also interesting
# https://www.python.org/dev/peps/pep-0427/ the official package format description
set(_MAKE_PYTHON_WHEEL_LIST_DIR "${CMAKE_CURRENT_LIST_DIR}")
function( MakeWheel python_module)
cmake_parse_arguments(MAKEWHEEL "PRINT_HELP" "MODULE;VERSION;SUMMARY;DESCRIPTION;HOMEPAGE;AUTHOR;EMAIL;LICENCE" "REQUIRES" ${ARGN} )
set(version ${MAKEWHEEL_VERSION})
execute_process(
COMMAND ${Python_EXECUTABLE} -c "
from setuptools.dist import Distribution
from setuptools import Extension
def wheel_name(**kwargs):
# create a fake distribution from arguments
dist = Distribution(attrs=kwargs)
# finalize bdist_wheel command
bdist_wheel_cmd = dist.get_command_obj('bdist_wheel')
bdist_wheel_cmd.ensure_finalized()
# assemble wheel file name
distname = bdist_wheel_cmd.wheel_dist_name
tag = '-'.join(bdist_wheel_cmd.get_tag())
return f'{distname};{tag}'
print(wheel_name(name='${python_module}', version='${version}', ext_modules=[Extension('dummy', ['summy.c'])]))
"
OUTPUT_VARIABLE wheel_filename
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(NOT wheel_filename)
message(STATUS "Python module `setuptools` required for correct wheel filename generation. Please install if needed.")
set(wheel_filename "unknown;unknown")
endif()
list(GET wheel_filename 0 distname)
list(GET wheel_filename 1 platformtag)
set(complete_tag "${distname}-${platformtag}")
set(wheel_filename "${CMAKE_BINARY_DIR}/${complete_tag}.whl")
set(wheel_distinfo "${CMAKE_BINARY_DIR}/${python_module}-${version}.dist-info")
set(wheel_data "${CMAKE_BINARY_DIR}/${python_module}-${version}.data")
set(wheel_generator_string "pango_wheelgen_${version}")
if( MAKEWHEEL_REQUIRES )
set(MAKEWHEEL_REQUIRES "Requires-Dist: ${MAKEWHEEL_REQUIRES}")
string(REPLACE ";" "\nRequires-Dist: " MAKEWHEEL_REQUIRES "${MAKEWHEEL_REQUIRES}")
endif()
##########################################
## Create dist info folder
file(GLOB wheel_info_files "${_MAKE_PYTHON_WHEEL_LIST_DIR}/wheel-dist-info/*" )
file(WRITE "${wheel_distinfo}/RECORD" "")
foreach(template_path ${wheel_info_files})
get_filename_component(template_name "${template_path}" NAME)
configure_file( ${template_path} "${wheel_distinfo}/${template_name}" )
file(SHA256 "${template_path}" file_sha)
file (SIZE "${template_path}" file_size)
file(APPEND "${wheel_distinfo}/RECORD" "${python_module}-${version}.dist-info/${template_name},sha256=${file_sha},${file_size}\n")
endforeach()
# TODO: Add line in RECORD for .so module itself (needs to be build time)
##########################################
## Place module into data folder
set_target_properties( ${python_module} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${wheel_data}/purelib")
##########################################
## Rule for creating file wheel zip
add_custom_command(
OUTPUT ${wheel_filename}
DEPENDS ${python_module}
COMMAND ${CMAKE_COMMAND} -E tar cf ${wheel_filename} --format=zip -- ${wheel_distinfo} ${wheel_data}
COMMENT "Creating Wheel ${wheel_filename}"
VERBATIM
)
##########################################
## Create a friendlier target name we can refer to
add_custom_target("${python_module}_wheel" DEPENDS "${wheel_filename}")
add_custom_target(
"${python_module}_pip_install"
DEPENDS "${python_module}_wheel"
COMMAND ${Python_EXECUTABLE} -mpip install "${wheel_filename}" --force-reinstall
COMMENT "Installing for selected Python '${Python_EXECUTABLE}'"
)
add_custom_target(
"${python_module}_pip_uninstall"
COMMAND ${Python_EXECUTABLE} -mpip uninstall -y ${python_module}
)
##########################################
## Help message since this is tricky for people
if(MAKEWHEEL_PRINT_HELP)
message(STATUS "Selected Python: '${Python_EXECUTABLE}'. cmake --build . -t ${python_module}_pip_install to use ${python_module} module.")
endif()
endfunction()