-
Notifications
You must be signed in to change notification settings - Fork 205
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
227 lines (196 loc) · 7.81 KB
/
Copy pathCMakeLists.txt
File metadata and controls
227 lines (196 loc) · 7.81 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
cmake_minimum_required(VERSION 3.16)
project(jpype-native)
option(ENABLE_TRACING "Enable tracing in the extension" OFF)
option(ENABLE_COVERAGE "Enable compilation for coverage measurement" OFF)
option(ENABLE_BUILD_JAR "Enable building of the Java JAR" ON)
option(BUILD_TEST_HARNESS "Build the Java test harness" ON)
# Optionally set Python GIL disabled flag
# set(PY_GIL_DISABLED ON)
set(CMAKE_CXX_STANDARD 14)
find_package(Python3 COMPONENTS Interpreter Development.Module REQUIRED)
find_package(Python3 COMPONENTS Development.Embed)
find_package(Java REQUIRED COMPONENTS Development)
find_package(JNI)
if(JNI_FOUND)
message(STATUS "System JNI found successfully.")
else()
message(STATUS "System JNI headers not found. Falling back to bundled jni.h.")
set(JNI_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/native/jni_include")
endif()
message(STATUS "Final JNI include dirs: ${JNI_INCLUDE_DIRS}")
if(SKBUILD)
message(DEBUG "SKBuild invocation")
set(DEST_JAR ${SKBUILD_PLATLIB_DIR})
set(DEST_EXTENSION ${SKBUILD_PLATLIB_DIR})
else()
# in-place build, set output to cmakes output dir.
set(DEST_JAR ${CMAKE_CURRENT_BINARY_DIR})
set(DEST_EXTENSION ${CMAKE_CURRENT_BINARY_DIR})
endif()
message(STATUS "Destination Python extension: ${DEST_EXTENSION}")
message(STATUS "Destination JAR: ${DEST_JAR}")
if(ENABLE_BUILD_JAR)
message(DEBUG "build jar")
find_program(ANT_EXECUTABLE ant REQUIRED)
# this is the build artifact of Ant.
set(JAR_OUTPUT "${CMAKE_SOURCE_DIR}/native/build/lib/org.jpype.jar")
# we also need to copy the JAR_OUTPUT to CMAKE_CURRENT_BINARY_DIR
add_custom_command(
OUTPUT "${JAR_OUTPUT}"
COMMAND "${ANT_EXECUTABLE}" -f "${CMAKE_SOURCE_DIR}/native/build.xml"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMENT "Building ${JAR_OUTPUT} with Apache Ant"
)
# link ant command with output jar
add_custom_target(jpype_jar ALL DEPENDS "${JAR_OUTPUT}")
# Copy the Ant build artifact to current cmake output dir (required for editable installs).
set(DEST_FILE "${CMAKE_CURRENT_BINARY_DIR}/org.jpype.jar")
add_custom_command(
OUTPUT "${DEST_FILE}"
COMMAND ${CMAKE_COMMAND} -E copy "${JAR_OUTPUT}" "${DEST_FILE}"
DEPENDS "${JAR_OUTPUT}" # ensures it only runs after the source exists
COMMENT "Copying ${JAR_OUTPUT} to internal destination"
)
add_custom_target(copy_jar ALL DEPENDS "${DEST_FILE}")
# Explicitly link targets so MSBuild doesn't run them in parallel.
add_dependencies(copy_jar jpype_jar)
# finally install the jar to DEST_JAR, which makes it available for wheel building.
install(
FILES "${DEST_FILE}"
DESTINATION ${DEST_JAR}
)
endif()
if(ENABLE_TRACING)
add_compile_definitions(JP_TRACING_ENABLE)
endif()
if(ENABLE_COVERAGE)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "ENABLE_COVERAGE set — forcing Debug build for coverage correctness")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE)
elseif(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(WARNING "ENABLE_COVERAGE set but CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}; coverage may be unreliable")
endif()
add_compile_definitions(JP_INSTRUMENTATION)
message(STATUS "Adding coverage instrumentation flags")
if(MSVC)
warn("Coverage not supported on windows.")
endif()
# Enable debug symbols
add_compile_options(-ggdb)
# Enable coverage instrumentation (GCC/Clang)
add_compile_options(-O0 --coverage -ftest-coverage)
add_link_options(--coverage)
endif()
if(BUILD_TEST_HARNESS)
find_program(ANT_EXECUTABLE ant REQUIRED)
# We define a representative output file to help CMake track dependencies
set(TEST_SENTINEL "${CMAKE_SOURCE_DIR}/test/classes/org/jpype/JPypeTest.class")
add_custom_command(
OUTPUT "${TEST_SENTINEL}"
COMMAND "${ANT_EXECUTABLE}" -f "test/build.xml"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
DEPENDS jpype_jar # Ensure the main org.jpype.jar is built first
COMMENT "Building JPype Java Test Harness via Ant"
)
add_custom_target(build_tests ALL DEPENDS "${TEST_SENTINEL}")
endif()
# C++ Python extension
include_directories(
native/common/include
native/python/include
${JNI_INCLUDE_DIRS}
)
set(JPYPE_NATIVE_SRC
native/common/jp_array.cpp
native/common/jp_arrayclass.cpp
native/common/jp_booleantype.cpp
native/common/jp_boxedtype.cpp
native/common/jp_buffer.cpp
native/common/jp_buffertype.cpp
native/common/jp_bytetype.cpp
native/common/jp_chartype.cpp
native/common/jp_class.cpp
native/common/jp_classhints.cpp
native/common/jp_classloader.cpp
native/common/jp_classtype.cpp
native/common/jp_context.cpp
native/common/jp_convert.cpp
native/common/jp_doubletype.cpp
native/common/jp_encoding.cpp
native/common/jp_exception.cpp
native/common/jp_field.cpp
native/common/jp_floattype.cpp
native/common/jp_functional.cpp
native/common/jp_gc.cpp
native/common/jp_inttype.cpp
native/common/jp_javaframe.cpp
native/common/jp_longtype.cpp
native/common/jp_method.cpp
native/common/jp_methoddispatch.cpp
native/common/jp_monitor.cpp
native/common/jp_numbertype.cpp
native/common/jp_objecttype.cpp
native/common/jp_platform.cpp
native/common/jp_primitivetype.cpp
native/common/jp_proxy.cpp
native/common/jp_reference_queue.cpp
native/common/jp_shorttype.cpp
native/common/jp_stringtype.cpp
native/common/jp_tracer.cpp
native/common/jp_typefactory.cpp
native/common/jp_typemanager.cpp
native/common/jp_value.cpp
native/common/jp_voidtype.cpp
native/python/jp_pythontypes.cpp
native/python/pyjp_array.cpp
native/python/pyjp_buffer.cpp
native/python/pyjp_char.cpp
native/python/pyjp_class.cpp
native/python/pyjp_classhints.cpp
native/python/pyjp_field.cpp
native/python/pyjp_method.cpp
native/python/pyjp_module.cpp
native/python/pyjp_monitor.cpp
native/python/pyjp_number.cpp
native/python/pyjp_object.cpp
native/python/pyjp_package.cpp
native/python/pyjp_proxy.cpp
native/python/pyjp_value.cpp
)
Python3_add_library(_jpype MODULE ${JPYPE_NATIVE_SRC})
target_link_libraries(_jpype PRIVATE Python3::Module)
# Set target properties for scikit-build export
set_target_properties(_jpype PROPERTIES
PREFIX "" # remove 'lib' prefix
)
set_target_properties(_jpype PROPERTIES OUTPUT_NAME "_jpype")
# Apply Windows-specific configuration
if(WIN32)
# Define WIN32 macro (Windows-specific code)
target_compile_definitions(_jpype PRIVATE WIN32=1)
# Required: .pyd suffix
set_target_properties(_jpype PROPERTIES SUFFIX ".pyd")
# Required: export all symbols for Python module
set_target_properties(_jpype PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
# Ensure /MD and exception model are set
target_compile_options(_jpype PRIVATE /EHsc /MD)
else()
# Additional libraries for non-Windows
target_link_libraries(_jpype PRIVATE
dl # dynamic linker
)
# Keep frame pointers for better stack unwinding.
add_compile_options(-fno-omit-frame-pointer)
# even on OSX Python uses .so suffix instead of .dylib
set_target_properties(_jpype PROPERTIES SUFFIX ".so")
endif()
# Only stage the extension into the wheel if scikit-build-core is building
if(SKBUILD)
message(STATUS "install _jpype extension to ${DEST_EXTENSION}")
install(TARGETS _jpype
LIBRARY DESTINATION ${DEST_EXTENSION}
RUNTIME DESTINATION ${DEST_EXTENSION}
)
else()
message(DEBUG "no skbuild env")
endif()