Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
numba
GitHub Repository: numba/llvmlite
Path: blob/main/ffi/CMakeLists.txt
1154 views
1
cmake_minimum_required(VERSION 3.13)
2
3
# This will define the name of the solution file in the build directory
4
project(llvmlite_ffi)
5
6
include(CheckIncludeFiles)
7
include(CheckLibraryExists)
8
include(CheckCXXCompilerFlag)
9
include(CMakePushCheckState)
10
# Work around llvm/llvm-project#83802 - LLVM's Findzstd.cmake uses variables
11
# that require including `GNUInstallDirs`, but it does not include it itself.
12
include(GNUInstallDirs)
13
14
set(CMAKE_CXX_STANDARD 17)
15
16
# Preset function visibility to hidden, API functions
17
# are annotated explicitly to use 'default' visibility.
18
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
19
set(CMAKE_C_VISIBILITY_PRESET "hidden")
20
21
find_package(LLVM REQUIRED CONFIG)
22
23
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
24
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
25
26
# NOTE: Keep this in sync with the version that llvmlite is declared to support
27
set(LLVMLITE_SUPPORTED_LLVM_VERSION_DEFAULT 20)
28
29
# Check LLVM version is supported or intentionally overridden.
30
if (NOT DEFINED LLVM_VERSION_MAJOR)
31
message(FATAL_ERROR "LLVM CMake export does not define LLVM_VERSION_MAJOR")
32
else()
33
if (LLVMLITE_SKIP_LLVM_VERSION_CHECK)
34
if (LLVM_VERSION_MAJOR EQUAL LLVMLITE_SUPPORTED_LLVM_VERSION_DEFAULT)
35
message(WARNING
36
"LLVMLITE_SKIP_LLVM_VERSION_CHECK is set but the current version \
37
${LLVMLITE_SUPPORTED_LLVM_VERSION_DEFAULT} is supported!")
38
else()
39
message(WARNING
40
"LLVMLITE_SKIP_LLVM_VERSION_CHECK is set, build is against an \
41
unsupported version of LLVM (${LLVM_VERSION_MAJOR}). Supported \
42
version is ${LLVMLITE_SUPPORTED_LLVM_VERSION_DEFAULT}.")
43
endif()
44
else()
45
if (NOT LLVM_VERSION_MAJOR EQUAL LLVMLITE_SUPPORTED_LLVM_VERSION_DEFAULT)
46
message(FATAL_ERROR
47
"LLVM CMake export states LLVM version is ${LLVM_VERSION_MAJOR}, \
48
llvmlite only officially supports \
49
${LLVMLITE_SUPPORTED_LLVM_VERSION_DEFAULT}.")
50
endif()
51
endif()
52
endif()
53
54
include_directories(${LLVM_INCLUDE_DIRS})
55
add_definitions(${LLVM_DEFINITIONS})
56
57
# Check for presence of the SVML patch in the LLVM build
58
set(CMAKE_REQUIRED_INCLUDES ${LLVM_INCLUDE_DIRS})
59
60
CHECK_INCLUDE_FILES("llvm/IR/SVML.inc" HAVE_SVML)
61
if(HAVE_SVML)
62
message(STATUS "SVML found")
63
add_definitions(-DHAVE_SVML)
64
else()
65
message(STATUS "SVML not found")
66
endif()
67
68
69
# Capture the package format
70
# LLVMLITE_PACKAGE_FORMAT the target package format, if set must be one of
71
# 'wheel' or 'conda', this is used by the llvmlite maintainers in testing.
72
73
# Keep in sync with config.cpp defines
74
set(LLVMLITE_PACKAGE_FORMAT_CONDA "1")
75
set(LLVMLITE_PACKAGE_FORMAT_WHEEL "2")
76
77
string(TOLOWER "${LLVMLITE_PACKAGE_FORMAT}" lowercase_LLVMLITE_PACKAGE_FORMAT)
78
if(lowercase_LLVMLITE_PACKAGE_FORMAT STREQUAL "conda" OR
79
lowercase_LLVMLITE_PACKAGE_FORMAT STREQUAL "wheel")
80
message(STATUS
81
"LLVMLITE_PACKAGE_FORMAT option is set, capturing this is a \
82
'${lowercase_LLVMLITE_PACKAGE_FORMAT}' format build")
83
if(lowercase_LLVMLITE_PACKAGE_FORMAT STREQUAL "conda")
84
add_definitions(
85
-DLLVMLITE_PACKAGE_FORMAT=${LLVMLITE_PACKAGE_FORMAT_CONDA})
86
else()
87
add_definitions(
88
-DLLVMLITE_PACKAGE_FORMAT=${LLVMLITE_PACKAGE_FORMAT_WHEEL})
89
endif()
90
message(STATUS
91
"LLVMLITE_PACKAGE_FORMAT is ${lowercase_LLVMLITE_PACKAGE_FORMAT}")
92
elseif("${lowercase_LLVMLITE_PACKAGE_FORMAT}" STREQUAL "")
93
# present but not set
94
else()
95
message(FATAL_ERROR "Invalid value for package format: \
96
'${LLVMLITE_PACKAGE_FORMAT}', expect one of 'conda' or 'wheel'.")
97
endif()
98
99
# RTTI handling: This is a little awkward, it's a 3-state variable so cannot be
100
# an option. The states are user defined as ON or OFF, or user has not set so
101
# inherit from LLVM. This part removes the `-fno-rtti` option from
102
# CMAKE_CXX_FLAGS if appropriate, `-fno-rtti` is then added back in later as
103
# a flag on the compilation target if the compiler supports it and no-RTTI was
104
# determined to be appropriate.
105
if(UNIX)
106
string(TOLOWER "${LLVMLITE_USE_RTTI}" lowercase_LLVMLITE_USE_RTTI)
107
if(lowercase_LLVMLITE_USE_RTTI STREQUAL "on")
108
message(STATUS
109
"LLVMLITE_USE_RTTI override is set, RTTI is ON.")
110
set(LLVMLITE_USE_RTTI_FLAG ON)
111
elseif(lowercase_LLVMLITE_USE_RTTI STREQUAL "off")
112
message(STATUS
113
"LLVMLITE_USE_RTTI override is set, RTTI is OFF.")
114
set(LLVMLITE_USE_RTTI_FLAG OFF)
115
elseif(lowercase_LLVMLITE_USE_RTTI STREQUAL "")
116
if(DEFINED LLVM_ENABLE_RTTI)
117
message(STATUS
118
"LLVMLITE_USE_RTTI not set, inheriting RTTI flags from LLVM as: \
119
${LLVM_ENABLE_RTTI}.")
120
set(LLVMLITE_USE_RTTI_FLAG ${LLVM_ENABLE_RTTI})
121
else()
122
message(FATAL_ERROR "Both LLVMLITE_USE_RTTI and LLVM_ENABLE_RTTI \
123
are not set, cannot inherit RTTI setting from \
124
LLVM, user must override by setting \
125
LLVMLITE_USE_RTTI")
126
endif()
127
else()
128
message(FATAL_ERROR "LLVMLITE_USE_RTTI is set to an unknown value:
129
${LLVMLITE_USE_RTTI}.")
130
endif()
131
132
# unconditionally strip out -fno-rtti, it will be added to the target
133
# if needed
134
set(FLAG_NO_RTTI "-fno-rtti")
135
set(OLD_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
136
separate_arguments(CMAKE_CXX_FLAGS_AS_LIST UNIX_COMMAND
137
"${CMAKE_CXX_FLAGS}")
138
list(FILTER CMAKE_CXX_FLAGS_AS_LIST EXCLUDE REGEX "^${FLAG_NO_RTTI}$")
139
string(JOIN " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_AS_LIST})
140
if(LLVMLITE_USE_RTTI_FLAG)
141
if(NOT ${OLD_CMAKE_CXX_FLAGS} STREQUAL ${CMAKE_CXX_FLAGS})
142
message(STATUS "-fno-rtti was removed from CXXFLAGS.")
143
else()
144
message(STATUS "-fno-rtti is not in CXXFLAGS, nothing to do.")
145
endif()
146
else()
147
# check the flag works.
148
check_cxx_compiler_flag(${FLAG_NO_RTTI} HAVE_FNO_RTTI)
149
if (NOT HAVE_FNO_RTTI)
150
message(FATAL_ERROR
151
"Compiler must support ${FLAG_NO_RTTI} option if it is requested")
152
endif()
153
endif()
154
endif()
155
156
# Define the shared library
157
add_library(llvmlite SHARED assembly.cpp bitcode.cpp config.cpp core.cpp initfini.cpp
158
module.cpp value.cpp executionengine.cpp type.cpp
159
targets.cpp dylib.cpp linker.cpp object_file.cpp
160
custom_passes.cpp orcjit.cpp memorymanager.cpp newpassmanagers.cpp)
161
162
163
# Determine whether libstdc++ should be statically linked (or not).
164
# GNU g++ and presumably clang on non-apple systems can probably deal with this.
165
if(UNIX AND NOT APPLE)
166
set(LLVMLITE_CXX_STATIC_LINK_DEFAULT OFF)
167
option(LLVMLITE_CXX_STATIC_LINK
168
"Enable C++ static linking in llvmlite (GNU Compilers)"
169
${LLVMLITE_CXX_STATIC_LINK_DEFAULT})
170
171
# See if static libc++ is requested
172
if (LLVMLITE_CXX_STATIC_LINK)
173
check_cxx_compiler_flag(-static-libstdc++ HAVE_STATIC_LIBSTDCXX)
174
if(NOT HAVE_STATIC_LIBSTDCXX)
175
message(FATAL_ERROR "LLVMLITE_CXX_STATIC_LINK was requested but
176
the compiler does not support the flag")
177
endif()
178
add_definitions(-DLLVMLITE_CXX_STATIC_LINK=1)
179
target_link_options(llvmlite PRIVATE -static-libstdc++)
180
endif()
181
endif()
182
183
# Apply no-RTTI flag if RTTI use is off, must happen after target definition
184
if(UNIX AND NOT LLVMLITE_USE_RTTI_FLAG)
185
message(STATUS "Applying no-RTTI flag to llvmlite target: ${FLAG_NO_RTTI}")
186
target_compile_options(llvmlite PRIVATE ${FLAG_NO_RTTI})
187
endif()
188
189
# Check for LTO / IPO
190
set(LLVMLITE_LTO_DEFAULT ON)
191
option(LLVMLITE_LTO "Enable LTO" ${LLVMLITE_LTO_DEFAULT})
192
193
if(LLVMLITE_LTO)
194
include(CheckIPOSupported)
195
check_ipo_supported(RESULT LLVMLITE_HAVE_LTO OUTPUT output)
196
if(LLVMLITE_HAVE_LTO)
197
message(STATUS "Enabling interprocedural optimization (LTO)")
198
set_property(TARGET llvmlite PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
199
else()
200
message(WARNING "IPO/LTO is not supported: ${output}")
201
endif()
202
else()
203
message(STATUS "IPO/LTO is disabled")
204
endif()
205
206
207
# Check if the LLVMLITE_SHARED build flag is set. Default is static. This option
208
# is baked into the binary for testing purposes.
209
# Find the libraries that correspond to the LLVM components needed based on the
210
# build flag.
211
set(LLVMLITE_SHARED_DEFAULT OFF)
212
option(LLVMLITE_SHARED
213
"Enable dynamic linkage against LLVM, default is OFF (i.e. static link)"
214
${LLVMLITE_SHARED_DEFAULT})
215
216
217
if (LLVMLITE_SHARED)
218
check_library_exists(LLVM LLVMGetVersion "" HAVE_LIBRARY_LLVM)
219
if(NOT HAVE_LIBRARY_LLVM)
220
message(FATAL_ERROR "Could not find libLLVM")
221
endif()
222
set(llvm_libs LLVM)
223
message(STATUS
224
"LLVMLITE_SHARED is ON, using dynamic linkage against LLVM")
225
add_definitions(-DHAVE_LLVMLITE_SHARED)
226
else()
227
# This doesn't work:
228
# llvm_map_components_to_libnames(llvm_libs all)
229
# xref: https://bugs.llvm.org/show_bug.cgi?id=47003
230
# This is a workaround based on knowing what is needed. Do not set llvm_libs
231
# to the cached LLVM_AVAILABLE_LIBS, it may contain the dynamic `LLVM`
232
# library, see https://github.com/numba/llvmlite/pull/1234 for discussion.
233
set(LLVM_COMPONENTS mcjit
234
orcjit
235
OrcDebugging
236
AsmPrinter
237
AllTargetsCodeGens
238
AllTargetsAsmParsers)
239
240
# Test build specific components, it's not known a priori whether these
241
# components will exist in a given build. On some platforms the components
242
# may not exist for good reason, e.g. IntelJITEvents won't exist on an
243
# aarch64 build, and equally, a custom LLVM may have mangled out the
244
# building of optional components or a packager may have split the llvm
245
# build such that a component is declared as present but is actually missing
246
# because it is in another package. Essentially, there's no real way of
247
# knowing and so each component is probed to check whether the mapped
248
# libname library exists by virtue of attempting a link.
249
250
# NOTE: To future editors, if you are upgrading LLVM and struggling to link,
251
# it could be because some component used by llvmlite has been renamed or
252
# split into two or similar. To resolve this, run `nm` on all the archive
253
# files in the LLVM build and grep for the missing symbols or vtable or
254
# whatever the linker is complaining about. Then add the name of the
255
# component that contains the missing item to either the list above if it
256
# could reasonably exist in all builds, or the list below if it's likely
257
# just some builds have the "new" component. Typically the "component" is
258
# just the name of the library without whatever the system considers as a
259
# libname and the "LLVM" prefix e.g. component IntelJITEvents corresponds to
260
# archive libLLVMIntelJITEvents.a. There are some "special"
261
# pseudo-components that have much broader expansions but it's unlikely
262
# these will be encountered.
263
set(LLVM_BUILD_SPECIFIC_COMPONENTS IntelJITEvents)
264
265
# This function checks for whether a specific LLVM component can be linked
266
function(check_optional_component COMPONENT CURRENT_COMPONENTS)
267
message(STATUS "Testing for LLVM component ${COMPONENT}")
268
cmake_push_check_state(RESET)
269
set(TEST_COMPONENT ${COMPONENT})
270
llvm_map_components_to_libnames(TEST_COMPONENT_LIB ${TEST_COMPONENT})
271
set(CMAKE_REQUIRED_LIBRARIES ${TEST_COMPONENT_LIB})
272
# Need a per-component name to make sure the cached value from previous
273
# run isn't reused, it also makes the STATUS output more clear.
274
set(TMP_HAVE_COMPONENT "HAVE_COMPONENT:${COMPONENT}")
275
check_cxx_source_compiles("int main(void){return 0;}"
276
${TMP_HAVE_COMPONENT})
277
cmake_pop_check_state()
278
if (${TMP_HAVE_COMPONENT})
279
list(APPEND CURRENT_COMPONENTS ${TEST_COMPONENT})
280
endif()
281
# write back into caller scope
282
set(LLVM_COMPONENTS ${CURRENT_COMPONENTS} PARENT_SCOPE)
283
endfunction()
284
285
# check each build specific component, if it's available it will be added to
286
# LLVM_COMPONENTS.
287
foreach(COMPONENT IN LISTS LLVM_BUILD_SPECIFIC_COMPONENTS)
288
check_optional_component(${COMPONENT} "${LLVM_COMPONENTS}")
289
endforeach()
290
291
# Map known components to library names for linkage
292
llvm_map_components_to_libnames(llvm_libs ${LLVM_COMPONENTS})
293
message(STATUS "LLVM_COMPONENTS: ${LLVM_COMPONENTS}")
294
message(STATUS
295
"LLVMLITE_SHARED is OFF, using static linkage against LLVM")
296
endif()
297
298
299
# If this is a static link to LLVM, bake in whether LLVM has assertions enabled.
300
# 3 states, on, off, and unknown
301
# Keep in sync with config.cpp defines
302
set(LLVMLITE_LLVM_ASSERTIONS_OFF "0")
303
set(LLVMLITE_LLVM_ASSERTIONS_ON "1")
304
set(LLVMLITE_LLVM_ASSERTIONS_UNKNOWN "2")
305
306
if(LLVMLITE_SHARED)
307
add_definitions(
308
-DLLVMLITE_LLVM_ASSERTIONS_STATE=${LLVMLITE_LLVM_ASSERTIONS_UNKNOWN})
309
message(STATUS "LLVM assertions state detected as 'unknown'")
310
else()
311
if(LLVM_ENABLE_ASSERTIONS)
312
add_definitions(
313
-DLLVMLITE_LLVM_ASSERTIONS_STATE=${LLVMLITE_LLVM_ASSERTIONS_ON})
314
message(STATUS "LLVM assertions state detected as 'on'")
315
else()
316
add_definitions(
317
-DLLVMLITE_LLVM_ASSERTIONS_STATE=${LLVMLITE_LLVM_ASSERTIONS_OFF})
318
message(STATUS "LLVM assertions state detected as 'off'")
319
endif()
320
endif()
321
322
323
# Setup and report on linkage against LLVM libraries
324
message(STATUS "LLVM target link libraries: ${llvm_libs}")
325
target_link_libraries(llvmlite ${llvm_libs})
326
327
# --exclude-libs allow removal of unused parts of LLVM
328
# TODO: these options are just set, they should really be tested for
329
# suitability.
330
if(UNIX AND NOT APPLE)
331
set(FORCED_LINK_FLAGS "-Wl,--exclude-libs,ALL -Wl,--no-undefined")
332
if(NOT LLVMLITE_SHARED)
333
# If LLVM is statically linked, we specify -Bsymbolic to prevent
334
# that LLVM symbols can be interposed upon by previously
335
# loaded shared objects that export LLVM symbols.
336
STRING(APPEND FORCED_LINK_FLAGS " -Wl,-Bsymbolic")
337
endif()
338
set_property(TARGET llvmlite APPEND_STRING PROPERTY LINK_FLAGS
339
"${FORCED_LINK_FLAGS}")
340
elseif(APPLE)
341
# On Darwin only include the LLVMPY symbols required and exclude
342
# everything else.
343
set(FORCED_LINK_FLAGS "-Wl,-exported_symbol,_LLVMPY_*")
344
set_property(TARGET llvmlite APPEND_STRING PROPERTY LINK_FLAGS
345
"${FORCED_LINK_FLAGS}")
346
endif()
347
348