-
Notifications
You must be signed in to change notification settings - Fork 643
/
CMakeLists.txt
280 lines (234 loc) · 8.51 KB
/
CMakeLists.txt
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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
cmake_minimum_required(VERSION 3.10.2)
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
project(coremltools)
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
message(FATAL_ERROR "
Source directory '${PROJECT_SOURCE_DIR}' is the same
as binary directory '${PROJECT_BINARY_DIR}'; coremltools requires
an out-of-source build. Note that your directory tree will require
you to remove CMakeCache.txt before this will work, and CMake may have
clobbered some source files (use git reset --hard).
See: https://gitlab.kitware.com/cmake/community/wikis/FAQ#i-run-an-out-of-source-build-but-cmake-generates-in-source-anyway-why
")
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Globally ignore "no symbols" warnings during compilation
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
if(APPLE)
SET(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
endif()
find_program(HAS_CCACHE ccache)
if(HAS_CCACHE)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif()
add_subdirectory(deps)
add_subdirectory(mlmodel)
find_package(PythonInterp)
find_package(PythonLibs)
message("Found python at ${PYTHON_EXECUTABLE}")
message("Found python version ${PYTHON_VERSION_STRING}")
message("Found python includes ${PYTHON_INCLUDE_DIRS}")
include_directories(
.
deps/protobuf/src
deps/pybind11/include
deps/nlohmann
mlmodel/src
${PYTHON_INCLUDE_DIRS}
)
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fobjc-arc")
endif()
add_library(milstoragepython
SHARED
milstoragepython/MilStorage.cpp
milstoragepython/MilStoragePython.cpp
)
target_link_libraries(milstoragepython
mlmodel
)
add_library(modelpackage
SHARED
modelpackage/src/ModelPackage.cpp
modelpackage/src/utils/JsonMap.cpp
modelpackage/src/ModelPackagePython.cpp
)
target_compile_definitions(modelpackage
PRIVATE
CPU_ONLY=1
)
target_link_libraries(modelpackage
mlmodel
libprotobuf
)
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1)
target_link_libraries(modelpackage
stdc++fs
)
endif()
if (APPLE)
# Allow Python to be found at runtime instead of compile/link time
# This is apparently the default on Linux
set_target_properties(milstoragepython PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
set_target_properties(modelpackage PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
endif()
file(COPY ${CMAKE_SOURCE_DIR}/README.md DESTINATION ${CMAKE_BINARY_DIR})
file(COPY ${CMAKE_SOURCE_DIR}/coremltools/__init__.py
DESTINATION ${CMAKE_BINARY_DIR}/coremltools)
file(COPY ${CMAKE_SOURCE_DIR}/coremltools/version.py
DESTINATION ${CMAKE_BINARY_DIR}/coremltools)
set(copy_dirs _deps converters models proto)
foreach(cdir IN ITEMS ${copy_dirs})
file(COPY ${CMAKE_SOURCE_DIR}/coremltools/${cdir}
DESTINATION ${CMAKE_BINARY_DIR}/coremltools)
endforeach()
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(_additional_milstoragepython_command COMMAND strip -x ${PROJECT_SOURCE_DIR}/coremltools/libmilstoragepython.so)
set(_additional_modelpackage_command COMMAND strip -x ${PROJECT_SOURCE_DIR}/coremltools/libmodelpackage.so)
endif()
add_custom_command(
TARGET modelpackage
POST_BUILD
COMMAND cp $<TARGET_FILE:modelpackage> ${PROJECT_SOURCE_DIR}/coremltools/libmodelpackage.so
${_additional_modelpackage_command}
)
if (NOT APPLE)
target_link_libraries(modelpackage uuid)
endif()
add_custom_command(
TARGET milstoragepython
POST_BUILD
COMMAND cp $<TARGET_FILE:milstoragepython> ${PROJECT_SOURCE_DIR}/coremltools/libmilstoragepython.so
${_additional_milstoragepython_command}
)
find_library(CORE_VIDEO CoreVideo)
find_library(CORE_ML CoreML)
find_library(FOUNDATION Foundation)
if (APPLE AND CORE_VIDEO AND CORE_ML AND FOUNDATION)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "import numpy; print(numpy.get_include())"
RESULT_VARIABLE NUMPY_INCLUDE_STATUS
OUTPUT_VARIABLE NUMPY_INCLUDE
)
if("${NUMPY_INCLUDE}" STREQUAL "" OR NOT NUMPY_INCLUDE_STATUS EQUAL 0)
message(FATAL_ERROR "Could not find numpy include path. Exit code: ${NUMPY_INCLUDE_STATUS}")
endif()
message("Found numpy include path at ${NUMPY_INCLUDE}")
include_directories(
${NUMPY_INCLUDE}
)
add_library(coremlpython
SHARED
coremlpython/CoreMLPython.mm
coremlpython/CoreMLPython.h
coremlpython/CoreMLPythonArray.mm
coremlpython/CoreMLPythonArray.h
coremlpython/CoreMLPythonUtils.mm
coremlpython/CoreMLPythonUtils.h
)
target_link_libraries(coremlpython
mlmodel
${CORE_VIDEO}
${CORE_ML}
${FOUNDATION}
)
set(osx_export_file ${CMAKE_SOURCE_DIR}/coremlpython/exported_symbols_osx.ver)
set_property(TARGET coremlpython APPEND PROPERTY LINK_DEPENDS "${osx_export_file}")
set_property(TARGET coremlpython APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-exported_symbols_list,${osx_export_file} ")
# Allow Python to be found at runtime instead of compile/link time
# This is apparently the default on Linux
set_property(TARGET coremlpython APPEND_STRING PROPERTY LINK_FLAGS "-undefined dynamic_lookup")
set_property(TARGET coremlpython APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-dead_strip")
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(_additional_libcoremlpython_command
COMMAND strip -x ${PROJECT_SOURCE_DIR}/coremltools/libcoremlpython.so
)
endif()
add_custom_command(
TARGET coremlpython
POST_BUILD
COMMAND cp $<TARGET_FILE:coremlpython> ${PROJECT_SOURCE_DIR}/coremltools/libcoremlpython.so
${_additional_libcoremlpython_command}
)
else()
message(STATUS "CoreML.framework and dependent frameworks not found. Skipping libcoremlpython build.")
endif()
# Build kmeans-1d
set(KMEANS_DIR "${PROJECT_SOURCE_DIR}/deps/kmeans1d")
execute_process(
COMMAND python3 setup.py build_ext --inplace
WORKING_DIRECTORY ${KMEANS_DIR}
)
# Somehow Python's setuptools is building this shared object file so that it tries to load the C++
# standard library using an rpath that only exist on the build machine. Change that so it gets
# loaded from the standard location.
if(APPLE)
file(GLOB SO_FILE "${PROJECT_SOURCE_DIR}/deps/kmeans1d/kmeans1d/_core.*.so")
execute_process(
COMMAND install_name_tool -change @rpath/libc++.1.dylib /usr/lib/libc++.1.dylib ${SO_FILE}
)
endif()
# Copy kmeans-1d to Python deps folder
execute_process(
COMMAND cp -r kmeans1d ../../coremltools/_deps
WORKING_DIRECTORY ${KMEANS_DIR}
)
set(PYTHON_TAG "cp${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}")
if(APPLE)
execute_process(COMMAND uname -m OUTPUT_VARIABLE HARDWARE_NAME OUTPUT_STRIP_TRAILING_WHITESPACE)
if(${HARDWARE_NAME} MATCHES "x86_64")
set(MIN_MAC_OS "10_15")
elseif(${HARDWARE_NAME} MATCHES "arm64")
set(MIN_MAC_OS "11_0")
else()
message(FATAL_ERROR "Unsupported hardware type. On macOS, x86_64 and arm64 are supported.")
endif()
set(PLAT_NAME "macosx_${MIN_MAC_OS}_${HARDWARE_NAME}")
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
set(PLAT_NAME "manylinux1_x86_64")
else()
message(FATAL_ERROR "Unsupported build platform. Supported platforms are Linux and macOS.")
endif()
if(BUILD_TAG)
set(BUILD_TAG_OPTION "--build-number=${BUILD_TAG}")
message(STATUS "Using ${BUILD_TAG} as build tag for wheels.")
else()
set(BUILD_TAG_OPTION "")
endif()
# Add a target for each platform, and then a 'dist' that will build all of them.
# Parallel invocations of setup.py is not safe, so we serialize them.
set(plat_targets "")
foreach(platform IN ITEMS ${PLAT_NAME})
add_custom_target(dist_${platform}
COMMENT "Building dist for platform ${platform}..."
COMMAND ${PYTHON_EXECUTABLE}
${CMAKE_SOURCE_DIR}/setup.py
bdist_wheel
--plat-name=${platform}
--python-tag=${PYTHON_TAG}
${BUILD_TAG_OPTION}
--dist-dir=${PROJECT_BINARY_DIR}/dist
DEPENDS "milstoragepython;modelpackage;coremlpython;${plat_targets}"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
set(plat_targets "${plat_targets};dist_${platform}")
endforeach()
# Add a 'dist' target that will build wheels for all possible platforms.
add_custom_target(dist DEPENDS ${plat_targets})
add_custom_target(pip_install_dev
COMMAND pip install -e ${PROJECT_SOURCE_DIR}
DEPENDS "coremlpython"
)
add_custom_target(pytest
COMMAND pytest -r fs ${PROJECT_SOURCE_DIR}/coremltools/test/ --timeout=600
DEPENDS pip_install_dev
USES_TERMINAL
)
add_custom_target(pytest_no_slow
COMMAND pytest -r fs -m '"no slow"' ${PROJECT_SOURCE_DIR}/coremltools/test/
DEPENDS pip_install_dev
USES_TERMINAL
)