-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
257 lines (219 loc) · 8.83 KB
/
CMakeLists.txt
File metadata and controls
257 lines (219 loc) · 8.83 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
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
cmake_minimum_required(VERSION 3.15)
project(ProXPL VERSION 1.2.0 LANGUAGES C CXX)
# Enable C and C++
enable_language(C CXX)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (MSVC)
add_compile_options(/W4 /wd4244 /wd4245 /wd4267 /wd4100 /wd4200)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
else()
add_compile_options(-Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter)
endif()
# --- Build Configuration ---
option(PROX_STATIC_BUILD "Build as a single static executable" ON)
if(PROX_STATIC_BUILD)
add_definitions(-DPROX_STATIC)
if(MSVC)
# Set dynamic/static CRT for the whole project before targets are added
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
# Also add flags for older CMake versions or explicit control
add_compile_options($<$<CONFIG:Release>:/MT> $<$<CONFIG:Debug>:/MTd>)
endif()
endif()
# --- LLVM Configuration ---
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules")
# Add explicit hints for LLVM on Windows
if(WIN32)
# First, verify if LLVM_DIR is set and valid
if(LLVM_DIR AND NOT EXISTS "${LLVM_DIR}/LLVMConfig.cmake")
message(WARNING "LLVM_DIR is set to '${LLVM_DIR}' but LLVMConfig.cmake not found there. Searching for LLVM...")
unset(LLVM_DIR CACHE)
endif()
# If LLVM_DIR is not set or invalid, search common paths
if(NOT LLVM_DIR)
message(STATUS "Searching for LLVM on Windows...")
set(LLVM_ROOT_HINTS
"$ENV{LLVM_ROOT}"
"$ENV{ProgramFiles}/LLVM"
"$ENV{ProgramFiles\(x86\)}/LLVM"
"C:/Program Files/LLVM"
"C:/Program Files (x86)/LLVM"
"C:/ProgramData/chocolatey/lib/llvm/tools/llvm"
)
set(LLVM_SEARCH_PATHS
"$ENV{LLVM_DIR}"
)
foreach(llvm_root ${LLVM_ROOT_HINTS})
if(llvm_root)
list(APPEND CMAKE_PREFIX_PATH "${llvm_root}")
list(APPEND LLVM_SEARCH_PATHS
"${llvm_root}/lib/cmake/llvm"
"${llvm_root}/lib/llvm/cmake"
"${llvm_root}/share/llvm/cmake"
"${llvm_root}/cmake"
)
endif()
endforeach()
list(REMOVE_DUPLICATES LLVM_SEARCH_PATHS)
foreach(search_path ${LLVM_SEARCH_PATHS})
if(search_path AND EXISTS "${search_path}/LLVMConfig.cmake")
set(LLVM_DIR "${search_path}" CACHE PATH "LLVM CMake directory")
message(STATUS "Found LLVM CMake files at: ${search_path}")
break()
endif()
endforeach()
endif()
endif()
# --- LLVM Configuration ---
if(WIN32)
# Try to find LLVM, but don't require it on Windows
find_package(LLVM CONFIG QUIET)
# Fallback for Windows if config not found (common with official installers)
if(NOT LLVM_FOUND)
message(STATUS "LLVM Config not found. Attempting manual detection via llvm-config...")
find_program(LLVM_CONFIG_EXE NAMES llvm-config llvm-config.exe
HINTS
"${LLVM_ROOT}/bin"
"$ENV{LLVM_ROOT}/bin"
"C:/LLVM/bin"
"C:/Program Files/LLVM/bin"
)
if(LLVM_CONFIG_EXE)
message(STATUS "Found llvm-config at: ${LLVM_CONFIG_EXE}")
execute_process(COMMAND ${LLVM_CONFIG_EXE} --includedir OUTPUT_VARIABLE LLVM_INCLUDE_DIRS OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${LLVM_CONFIG_EXE} --libdir OUTPUT_VARIABLE LLVM_LIBRARY_DIRS OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${LLVM_CONFIG_EXE} --version OUTPUT_VARIABLE LLVM_PACKAGE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
# Convert to CMake paths
file(TO_CMAKE_PATH "${LLVM_INCLUDE_DIRS}" LLVM_INCLUDE_DIRS)
file(TO_CMAKE_PATH "${LLVM_LIBRARY_DIRS}" LLVM_LIBRARY_DIRS)
set(LLVM_FOUND TRUE)
set(LLVM_VERSION ${LLVM_PACKAGE_VERSION})
endif()
endif()
else()
# LLVM is required on Unix platforms
find_package(LLVM CONFIG REQUIRED)
endif()
if(NOT LLVM_FOUND)
if(WIN32)
message(WARNING "LLVM not found. Building without LLVM backend support on Windows.")
else()
message(FATAL_ERROR "LLVM not found! Please install LLVM and set LLVM_DIR.")
endif()
else()
# Ensure LLVM_INCLUDE_DIRS is set (sometimes it's LLVM_INCLUDE_DIR)
if(NOT LLVM_INCLUDE_DIRS AND LLVM_INCLUDE_DIR)
set(LLVM_INCLUDE_DIRS ${LLVM_INCLUDE_DIR})
endif()
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "LLVM Include Dirs: ${LLVM_INCLUDE_DIRS}")
message(STATUS "LLVM Library Dirs: ${LLVM_LIBRARY_DIRS}")
message(STATUS "LLVM Definitions: ${LLVM_DEFINITIONS}")
endif()
# --- LibFFI Configuration ---
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(LIBFFI libffi)
endif()
if(NOT LIBFFI_FOUND)
find_path(LIBFFI_INCLUDE_DIRS ffi.h)
find_library(LIBFFI_LIBRARIES NAMES ffi libffi)
if(LIBFFI_INCLUDE_DIRS AND LIBFFI_LIBRARIES)
set(LIBFFI_FOUND TRUE)
endif()
endif()
if(LIBFFI_FOUND)
message(STATUS "Found LibFFI: ${LIBFFI_LIBRARIES}")
include_directories(${LIBFFI_INCLUDE_DIRS})
add_definitions(-DUSE_LIBFFI)
else()
message(WARNING "LibFFI not found. FFI features will be disabled.")
endif()
if(LLVM_FOUND)
if(COMMAND llvm_map_components_to_libnames)
llvm_map_components_to_libnames(llvm_libs core support executionengine native ipo analysis transformutils bitwriter)
elseif(LLVM_CONFIG_EXE)
# Fallback for when LLVMConfig.cmake is missing but llvm-config works
execute_process(COMMAND ${LLVM_CONFIG_EXE} --libnames core support executionengine native ipo analysis transformutils bitwriter
OUTPUT_VARIABLE llvm_libs OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE " " ";" llvm_libs "${llvm_libs}")
else()
# Final fallback: just try common library names
set(llvm_libs LLVMCore LLVMSupport LLVMExecutionEngine LLVMAnalysis LLVMTarget)
endif()
endif()
# Export symbols for Windows DLL
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
# --- Include Directories ---
include_directories(include)
include_directories(src)
# List of all C/C++ source files for the library, excluding those with a 'main' function
file(GLOB_RECURSE LIB_SOURCES "src/*.c")
file(GLOB_RECURSE LIB_SOURCES_CPP "src/*.cpp")
# Handle LLVM Backend Source: Only include if LLVM was found
if(LLVM_FOUND)
message(STATUS "LLVM backend enabled - including backend_llvm.cpp")
else()
message(STATUS "LLVM backend disabled - excluding backend_llvm.cpp")
list(REMOVE_ITEM LIB_SOURCES_CPP "${CMAKE_CURRENT_SOURCE_DIR}/src/compiler/backend_llvm.cpp")
endif()
list(APPEND LIB_SOURCES ${LIB_SOURCES_CPP})
# Explicitly exclude files that contain a 'main()' function or are specific VM implementations
list(REMOVE_ITEM LIB_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/main.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/vm/vm_v2.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/vm/vm_register.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/instr_handlers_template.c"
)
# Define the core library that all tools link against
add_library(prox_core STATIC ${LIB_SOURCES})
target_include_directories(prox_core PUBLIC include src)
if (LLVM_FOUND)
target_include_directories(prox_core PRIVATE ${LLVM_INCLUDE_DIRS})
target_compile_definitions(prox_core PRIVATE USE_LLVM_BACKEND)
# Apply LLVM compile definitions globally as some headers might need them
add_definitions(${LLVM_DEFINITIONS})
target_link_libraries(prox_core PUBLIC ${llvm_libs})
endif()
if (LIBFFI_FOUND)
target_link_libraries(prox_core PUBLIC ${LIBFFI_LIBRARIES})
endif()
# Main executable
add_executable(proxpl src/main.c)
target_link_libraries(proxpl PRIVATE prox_core)
if(UNIX)
if(APPLE)
target_link_libraries(proxpl PRIVATE pthread dl z)
else()
target_link_libraries(proxpl PRIVATE pthread dl z tinfo)
endif()
endif()
# --- IR Test Executable ---
add_executable(ir_gen_test tools/ir_gen_test.c)
target_link_libraries(ir_gen_test PRIVATE prox_core)
# --- LLVM Gen Test Executable ---
add_executable(llvm_gen_test tools/llvm_gen_test.c)
target_link_libraries(llvm_gen_test PRIVATE prox_core)
# --- PRM Executable ---
add_executable(prm tools/prm_main.c)
target_link_libraries(prm PRIVATE prox_core)
if(UNIX)
if(APPLE)
target_link_libraries(prm PRIVATE pthread dl z)
else()
target_link_libraries(prm PRIVATE pthread dl z tinfo)
endif()
endif()
# --- Optional components ---
option(BUILD_TESTS "Build tests" OFF)
option(BUILD_BENCH "Build benchmarks" OFF)
if (BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
if (BUILD_BENCH)
add_subdirectory(tools/bench)
endif()