Skip to content

Commit cfc853a

Browse files
committed
Setup CMake project files to build ASN.1 extensions
--- icspacket-defs: + Includes common CMake defines + Add workaround for Windows CI icspacket-common: + Add interface to register new ASN.1 extensions quickly
1 parent 51e60ca commit cfc853a

3 files changed

Lines changed: 152 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
cmake_minimum_required(VERSION 3.15...3.26)
2+
project(${SKBUILD_PROJECT_NAME} LANGUAGES C)
3+
4+
# This CMake file is meant to be executed using 'scikit-build-core'.
5+
if (NOT SKBUILD)
6+
message(WARNING "\
7+
This CMake file is meant to be executed using 'scikit-build-core'.
8+
Running it directly will almost certainly not produce the desired
9+
result. If you are a user trying to install this package, use the
10+
command below, which will install all necessary build dependencies,
11+
compile the package in an isolated environment, and then install it.
12+
=====================================================================
13+
$ pip install .
14+
=====================================================================
15+
If you are a software developer, and this is your own package, then
16+
it is usually much more efficient to install the build dependencies
17+
in your environment once and use the following command that avoids
18+
a costly creation of a new virtual environment at every compilation:
19+
=====================================================================
20+
$ pip install pybind11 scikit-build-core[pyproject]
21+
$ pip install --no-build-isolation -ve .
22+
=====================================================================
23+
You may optionally add -Ceditable.rebuild=true to auto-rebuild when
24+
the package is imported. Otherwise, you need to rerun the above
25+
after editing C++ files.")
26+
endif()
27+
28+
include(cmake/icspacket-common.cmake)
29+
include(cmake/icspacket-defs.cmake)
30+
31+
# -----------------------------------------------------------------------------
32+
# icspacket ASN.1 extensions
33+
# -----------------------------------------------------------------------------

cmake/icspacket-common.cmake

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# icspacket-common.cmake
2+
# Defines a helper function for building ASN.1-based Python C extensions
3+
# -----------------------------------------------------------------------------
4+
5+
# -----------------------------------------------------------------------------
6+
# Usage
7+
#
8+
# # Minimal usage: build an extension from MOD_DIR sources
9+
# add_asn1_extension(
10+
# mymodule # Python extension name
11+
# ${ICS_SOURCE_DIR}/proto/mymodule/_mymodule # Sources directory
12+
# proto/mymodule # Install subdirectory
13+
# )
14+
function(add_asn1_extension MOD_NAME MOD_DIR INSTALL_SUBDIR)
15+
# Parse function arguments
16+
set(options) # (reserved for future boolean flags)
17+
set(one_value_args) # (reserved for single-value args)
18+
set(multi_value_args EXTRA_SOURCES INCLUDES DEFINITIONS)
19+
20+
cmake_parse_arguments(
21+
ASN1
22+
"${options}"
23+
"${one_value_args}"
24+
"${multi_value_args}"
25+
${ARGN}
26+
)
27+
28+
file(GLOB MOD_SOURCES "${MOD_DIR}/*.c")
29+
python_add_library(
30+
${MOD_NAME}
31+
MODULE
32+
${ICS_BASE_SOURCES}
33+
${MOD_SOURCES}
34+
${ASN1_EXTRA_SOURCES}
35+
WITH_SOABI
36+
)
37+
38+
message(STATUS "======================= [${MOD_NAME}] =======================")
39+
message(STATUS "Adding ASN.1 extension: ${MOD_NAME} (sources in ${MOD_DIR})")
40+
41+
target_include_directories(
42+
${MOD_NAME}
43+
PRIVATE
44+
"${ICS_INCLUDE_DIR}/skeletons"
45+
"${MOD_DIR}"
46+
${ASN1_INCLUDES}
47+
)
48+
if(ASN1_DEFINITIONS)
49+
target_compile_definitions(${MOD_NAME} PRIVATE ${ASN1_DEFINITIONS})
50+
message(STATUS "Extra definitions: ${ASN1_DEFINITIONS}")
51+
endif()
52+
53+
# Install into the Python package namespace under INSTALL_SUBDIR
54+
install(
55+
TARGETS ${MOD_NAME}
56+
DESTINATION ${SKBUILD_PROJECT_NAME}/${INSTALL_SUBDIR}
57+
)
58+
endfunction()
59+

cmake/icspacket-defs.cmake

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
if(CMAKE_VERSION VERSION_LESS 3.18)
3+
set(DEV_MODULE Development)
4+
else()
5+
set(DEV_MODULE Development.Module)
6+
endif()
7+
8+
find_package(Python REQUIRED COMPONENTS Interpreter ${DEV_MODULE})
9+
10+
# -----------------------------------------------------------------------------
11+
# Workaround for Windows: construct Python_LIBRARY if not set
12+
# (common in CI with hostedtoolcache)
13+
# -----------------------------------------------------------------------------
14+
if(WIN32 AND NOT DEFINED Python_LIBRARY)
15+
# Dynamically construct the Python_LIBRARY path using version info from
16+
# find_package(Python)
17+
if (NOT Python_VERSION)
18+
message(FATAL_ERROR
19+
"Python_VERSION not set after find_package(Python). "
20+
"Cannot construct Python library path."
21+
)
22+
endif()
23+
24+
# Split the version string into major, minor, and patch parts
25+
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.(.+)" _ ${Python_VERSION})
26+
set(Python_VERSION_MAJOR ${CMAKE_MATCH_1})
27+
set(Python_VERSION_MINOR ${CMAKE_MATCH_2})
28+
set(Python_VERSION_PATCH ${CMAKE_MATCH_3})
29+
30+
set(DYNAMIC_PYTHON_LIB_FILENAME "python${Python_VERSION_MAJOR}${Python_VERSION_MINOR}.lib")
31+
set(EXPECTED_PYTHON_VERSION_DIR "C:/hostedtoolcache/windows/Python/${Python_VERSION}/x64/libs")
32+
set(Python_LIBRARY "${EXPECTED_PYTHON_VERSION_DIR}/${DYNAMIC_PYTHON_LIB_FILENAME}")
33+
34+
message(STATUS "DEBUG: On Windows, constructed DYNAMIC_PYTHON_LIB_FILENAME: ${DYNAMIC_PYTHON_LIB_FILENAME}")
35+
message(STATUS "DEBUG: On Windows, constructed Python_LIBRARY path: ${Python_LIBRARY}")
36+
endif()
37+
38+
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
39+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
40+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
41+
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
42+
endif()
43+
44+
# -----------------------------------------------------------------------------
45+
# Project-specific include and source directories for the ICS packet module.
46+
# -----------------------------------------------------------------------------
47+
set(ICS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/icspacket/include")
48+
set(ICS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/icspacket")
49+
50+
# Collect all base source files under "skeletons" for compilation. This globbing
51+
# automatically pulls in all .c files. We can do that here, because the
52+
# skeletons directory is designed to store only C source and header files.
53+
file(GLOB ICS_BASE_SOURCES "${ICS_INCLUDE_DIR}/skeletons/*.c")
54+
55+
# -----------------------------------------------------------------------------
56+
# Optional debugging flag:
57+
# Enable ASN.1 debugging output from asn1c-generated code.
58+
# Uncomment this line during development/troubleshooting.
59+
# -----------------------------------------------------------------------------
60+
# add_definitions(-DASN_EMIT_DEBUG=1)

0 commit comments

Comments
 (0)