Files
rapidyaml/api/CMakeLists.txt
Joao Paulo Magalhaes 5e7596d97f Improve python API:
- expose `to_arena()`
- improve type handling in Tree methods accepting scalars
2025-12-28 13:13:57 +00:00

172 lines
6.3 KiB
CMake

option(RYML_BUILD_API_PYTHON "Enable Python API" ON)
option(RYML_API_TESTS "Enable API tests" ${RYML_BUILD_TESTS})
option(RYML_API_BENCHMARKS "Enable API tests" ${RYML_BUILD_BENCHMARKS})
c4_log("enabling API")
cmake_policy(PUSH)
# UseSWIG generates standard target names.
# https://cmake.org/cmake/help/latest/policy/CMP0078.html
cmake_policy(SET CMP0078 NEW)
# UseSWIG honors SWIG_MODULE_NAME via -module flag.
# https://cmake.org/cmake/help/latest/policy/CMP0086.html
cmake_policy(SET CMP0086 NEW)
# Modules FindPython3, FindPython2 and FindPython use LOCATION for lookup strategy.
# https://cmake.org/cmake/help/latest/policy/CMP0094.html
cmake_policy(SET CMP0094 NEW)
find_package(SWIG REQUIRED)
c4_log("found swig ${SWIG_VERSION}: ${SWIG_EXECUTABLE}")
# https://cmake.org/cmake/help/v3.13/module/UseSWIG.html
include(UseSWIG)
if(NOT RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS)
message(FATAL_ERROR "API requires exceptions")
endif()
set(RYML_API_DIR ${CMAKE_CURRENT_LIST_DIR})
set(RYML_SWIG_SRC ${RYML_API_DIR}/ryml.i)
include(../ext/c4core/cmake/TargetArchitecture.cmake)
c4_get_architecture_defines(RYML_SWIG_ARCH_DEFINES)
c4_log("add CPU architecture defines ${RYML_SWIG_ARCH_DEFINES}")
foreach(f ${RYML_SWIG_SRC})
set_source_files_properties(${f} PROPERTIES
CPLUSPLUS ON
SWIG_MODULE_NAME ryml
SWIG_FLAGS "-includeall"
#INCLUDE_DIRECTORIES "${RYML_SRC_DIR}" # this needs quotes here!
)
endforeach()
add_custom_target(ryml-api-build)
c4_set_folder_remote_project_targets("api" ryml-api-build)
if(RYML_API_TESTS)
add_custom_target(ryml-api-test
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure ${${_c4_uprefix}CTEST_OPTIONS} -C $<CONFIG> -R "*api*"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
c4_set_folder_remote_project_targets("test" ryml-api-test)
endif()
if(RYML_API_BENCHMARKS)
add_custom_target(ryml-api-bm)
c4_set_folder_remote_project_targets("bm" ryml-api-bm)
endif()
if(RYML_BUILD_API_PYTHON)
c4_log("enabling python3 API")
set(Python3_FIND_VIRTUALENV "FIRST")
if(APPLE)
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
else()
# use Development.Module to ensure this works with cibuildwheel:
# https://github.com/pypa/cibuildwheel/issues/639
find_package(Python3 COMPONENTS Interpreter Development.Module REQUIRED)
endif()
c4_log("found python:
ver=${Python3_VERSION}
exe=${Python3_EXECUTABLE}
lib=${Python3_LIBRARIES}
inc=${Python3_INCLUDE_DIRS}
")
#
set(t ryml-api-python3) # the target name
set(g ${CMAKE_CURRENT_BINARY_DIR}/src/python3) # where to put c++ generated srcs
set(r ${CMAKE_CURRENT_BINARY_DIR}/python3) # where to put the py files/libs
#
# alternative 1: roll out the extension using cmake
#
c4_get_transitive_property(ryml SOURCES ryml_srcs)
c4_get_transitive_property(ryml INCLUDE_DIRECTORIES ryml_incs)
swig_add_library(${t}
LANGUAGE python
OUTPUT_DIR ${r}
OUTFILE_DIR ${g}
SOURCES ${RYML_SWIG_SRC} ${ryml_srcs})
#c4_set_folder_remote_project_targets("api" ${t})
add_dependencies(ryml-api-build ${t})
target_include_directories(${t} PUBLIC ${ryml_incs})
swig_link_libraries(${t} ${Python3_LIBRARIES})
set_target_properties(${t} PROPERTIES
OUTPUT_NAME "ryml"
SWIG_GENERATED_INCLUDE_DIRECTORIES ${Python3_INCLUDE_DIRS}
ARCHIVE_OUTPUT_DIRECTORY "${r}/lib"
LIBRARY_OUTPUT_DIRECTORY "${r}"
RUNTIME_OUTPUT_DIRECTORY "${r}")
if(WIN32)
target_compile_definitions(${t} PUBLIC __WIN32__)
elseif(APPLE)
set_property(TARGET ${t} APPEND PROPERTY LINK_FLAGS "-flat_namespace")
endif()
c4_get_transitive_property(ryml COMPILE_DEFINITIONS ryml_defs)
target_compile_definitions(${t} PUBLIC ${RYML_SWIG_ARCH_DEFINES} ${ryml_defs})
# Install the SWIG .so/.dll file
install(
TARGETS ${t}
COMPONENT python
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}
ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
get_property(WRAPPER_PY_FILE
TARGET ${t}
PROPERTY SWIG_SUPPORT_FILES)
# Install the .py file
install(
FILES ${WRAPPER_PY_FILE}
COMPONENT python
DESTINATION ${CMAKE_INSTALL_PREFIX})
set(pydir ${CMAKE_CURRENT_LIST_DIR}/python)
if(RYML_API_TESTS)
add_custom_target(ryml-api-test-python3
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure ${${_c4_uprefix}CTEST_OPTIONS} -C $<CONFIG> -R ".*python3.*"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${t}
)
add_dependencies(ryml-api-test ryml-api-test-python3)
c4_set_folder_remote_project_targets("test" ryml-api-test-python3)
function(add_python_test script)
get_filename_component(script_name ${script} NAME_WE)
set(script ${pydir}/tests/${script})
set(tn ryml-api-test-python3-${script_name})
set(cmd python ${script})
add_custom_target(${tn}
COMMAND ${cmd}
DEPENDS ${t})
c4_set_folder_remote_project_targets("test" ${tn})
add_test(NAME ${tn}-run
COMMAND ${cmd})
endfunction()
add_python_test(test_ryml.py)
endif()
if(RYML_API_BENCHMARKS)
add_custom_target(ryml-api-bm-python3)
add_dependencies(ryml-api-bm ryml-api-bm-python3)
c4_set_folder_remote_project_targets("bm" ryml-api-bm-python3)
set(script ${pydir}/ryml/tests/parse_bm.py)
c4_add_benchmark_cmd(ryml-api-bm-python3-travis
COMMAND python ${script} ${CMAKE_CURRENT_LIST_DIR}/../bm/cases/travis.yml ryml)
c4_add_benchmark_cmd(ryml-api-bm-python3-appveyor
COMMAND python ${script} ${CMAKE_CURRENT_LIST_DIR}/../bm/cases/appveyor.yml ryml)
c4_add_benchmark_cmd(ryml-api-bm-python3-compile_commands
COMMAND python ${script} ${CMAKE_CURRENT_LIST_DIR}/../bm/cases/compile_commands.json ryml)
c4_set_folder_remote_project_targets("bm" ryml-bm-api-python3-travis)
c4_set_folder_remote_project_targets("bm" ryml-bm-api-python3-appveyor)
c4_set_folder_remote_project_targets("bm" ryml-bm-api-python3-compile_commands)
endif()
endif()
cmake_policy(POP)