1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
cmake_minimum_required(VERSION 3.19)
project(pybcj C CXX)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# TARGET PYTHON version
set(PY_VERSION 3.12)
set(Python_FIND_IMPLEMENTATIONS CPython)
set(VENV_PATH "${CMAKE_BINARY_DIR}/venv")
set(DEBUG_BUILD ON)
# ##################################################################################################
# Configuration for python-ext
set(Python_FIND_STRATEGY VERSION)
find_package(Python ${PY_VERSION}.0...${PY_VERSION}.99 COMPONENTS Interpreter Development)
set(PY_EXT_FILE _bcj)
set(PY_EXT_DIR src/bcj)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/get_ext.py
"import sysconfig\nprint(sysconfig.get_config_var('EXT_SUFFIX'))\n")
execute_process(
COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/get_ext.py
OUTPUT_VARIABLE PY_EXT_EXT
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(PY_EXT ${PY_EXT_DIR}/${PY_EXT_FILE}.${PY_EXT_EXT})
set(PY_CFFI ${PY_CFFI_DIR}/PY_CFFI_FILE}.${PY_EXT_EXT})
# bulid ext by setup.py
if (WIN32)
if(DEBUG_BUILD)
set(BUILD_EXT_PYTHON ${VENV_PATH}/Scripts/python_d.exe)
else()
set(BUILD_EXT_PYTHON ${VENV_PATH}/Scripts/python.exe)
endif()
set(BUILD_EXT_OPTION)
else()
set(BUILD_EXT_PYTHON ${VENV_PATH}/bin/python)
set(BUILD_EXT_OPTION --warning-as-error)
endif()
set(pybcj_sources src/ext/Bra.c src/ext/Bra86.c src/ext/BraIA64.c)
set(pybcj_ext_src src/ext/_bcjmodule.c)
add_custom_target(
generate_ext
BYPRODUCTS ${PY_EXT}
COMMAND ${BUILD_EXT_PYTHON} setup.py build_ext ${BUILD_EXT_OPTION} --inplace
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS venv.stamp
SOURCES ${pybcj_sources} ${pybcj_ext_src})
add_library(_pybcj_ext MODULE ${pybcj_sources} ${pybcj_ext_src})
target_include_directories(_pybcj_ext PRIVATE ${Python_INCLUDE_DIRS} src/ext)
target_link_libraries(_pybcj_ext PRIVATE ${Python_LIBRARIES})
# ##################################################################################################
# create virtualenv
file(
WRITE ${CMAKE_CURRENT_BINARY_DIR}/requirements.txt
"
hypothesis
pytest>=6.0
")
if (WIN32)
set(PIP_COMMAND ${VENV_PATH}/Scripts/pip.exe)
else()
set(PIP_COMMAND ${VENV_PATH}/bin/pip)
endif()
add_custom_target(
venv.stamp
BYPRODUCTS venv.stamp
COMMAND ${Python_EXECUTABLE} -m venv ${VENV_PATH}
COMMAND ${PIP_COMMAND} install -r ${CMAKE_BINARY_DIR}/requirements.txt
COMMAND ${CMAKE_COMMAND} -E touch venv.stamp)
set(SRC_PATH "${CMAKE_SOURCE_DIR}/src")
set(VPKG_PATH_A "${VENV_PATH}/lib/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/site-packages/")
set(VPKG_PATH_B "${VENV_PATH}/Lib/site-packages/")
set(VPKG_PATH_C "${CMAKE_BINARY_DIR}")
# ##################################################################################################
# For pytest
file(
WRITE ${CMAKE_CURRENT_BINARY_DIR}/pytest_runner.cpp
"
#include <string>
#include <filesystem>
#include <unistd.h>
int main(int argc, char **argv) {
std::string args;
if ( argc > 1) {
args.append(\"[\");
for (int i = 1; i < argc; i++) {
if (i > 2)
args.append(\",\");
args.append(\"\\\"\");
args.append(argv[i]);
args.append(\"\\\"\");
}
args.append(\"]\");
}
std::filesystem::path src_path = \"${SRC_PATH}\";
std::filesystem::path vsite_path_a = \"${VPKG_PATH_A}\";
std::filesystem::path vsite_path_b = \"${VPKG_PATH_B}\";
std::filesystem::path vsite_path_c = \"${VPKG_PATH_C}\";
std::string pycode =
\"import sys\\n\"
\"sys.path.append('\" + src_path.string() + \"')\\n\"
\"sys.path.append('\" + vsite_path_a.string() + \"')\\n\"
\"sys.path.append('\" + vsite_path_b.string() + \"')\\n\"
\"import pytest\\n\"
\"pytest.main(\" + args + \")\\n\";
execl(\"${Python_EXECUTABLE}\", \"${Python_EXECUTABLE}\", \"-c\", pycode.c_str(), (char*)0);
return 0;
}")
add_executable(pytest_runner ${CMAKE_CURRENT_BINARY_DIR}/pytest_runner.cpp)
target_include_directories(pytest_runner PRIVATE ${Python_INCLUDE_DIRS})
target_link_libraries(pytest_runner PRIVATE ${Python_LIBRARIES})
add_dependencies(pytest_runner venv.stamp generate_ext)
|