-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsuperbuild.cmake
202 lines (179 loc) · 7.46 KB
/
superbuild.cmake
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
include_guard()
option(BUILD_SHARED_LIBS "Build using shared libraries" OFF)
# Bail out early for multi-config generators
if(CMAKE_CONFIGURATION_TYPES)
message(FATAL_ERROR "Multi-config generators are not supported. Use Make/NMake/Ninja instead")
endif()
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build")
endif()
# Default to a Release config
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "")
if(CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
endif()
message(STATUS "Configuration: ${CMAKE_BUILD_TYPE}")
# Default to build/install (setting this variable is not recommended and might cause conflicts)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/../install" CACHE PATH "Install prefix" FORCE)
endif()
message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}")
# Save the host platform in the install prefix
make_directory(${CMAKE_INSTALL_PREFIX})
file(TOUCH ${CMAKE_INSTALL_PREFIX}/${CMAKE_SYSTEM}.build)
# Git is necessary for submodules
find_package(Git REQUIRED)
message(STATUS "Git: ${GIT_EXECUTABLE}")
# Ninja is necessary for building the dependencies
find_program(ninja_EXECUTABLE ninja NO_CACHE NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_INSTALL_PREFIX NO_CMAKE_FIND_ROOT_PATH)
if(ninja_EXECUTABLE STREQUAL "ninja_EXECUTABLE-NOTFOUND")
message(FATAL_ERROR "Could not find 'ninja' in the PATH")
endif()
message(STATUS "Ninja: ${ninja_EXECUTABLE}")
# Ninja is necessary for building the dependencies
find_program(meson_EXECUTABLE meson NO_CACHE NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_INSTALL_PREFIX NO_CMAKE_FIND_ROOT_PATH)
if(meson_EXECUTABLE STREQUAL "meson_EXECUTABLE-NOTFOUND")
message(FATAL_ERROR "Could not find 'meson' in the PATH")
endif()
message(STATUS "meson: ${meson_EXECUTABLE}")
# On macOS, search Homebrew for keg-only versions of Bison and Flex. Xcode does
# not provide new enough versions for us to use.
if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
execute_process(
COMMAND brew --prefix bison
RESULT_VARIABLE BREW_BISON
OUTPUT_VARIABLE BREW_BISON_PREFIX
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(BREW_BISON EQUAL 0 AND EXISTS "${BREW_BISON_PREFIX}")
message(STATUS "Found Bison keg installed by Homebrew at ${BREW_BISON_PREFIX}")
set(BISON_EXECUTABLE "${BREW_BISON_PREFIX}/bin/bison")
else()
message(FATAL_ERROR "Bison not found, to install: brew install bison")
endif()
execute_process(
COMMAND brew --prefix flex
RESULT_VARIABLE BREW_FLEX
OUTPUT_VARIABLE BREW_FLEX_PREFIX
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(BREW_FLEX EQUAL 0 AND EXISTS "${BREW_FLEX_PREFIX}")
message(STATUS "Found Flex keg installed by Homebrew at ${BREW_FLEX_PREFIX}")
set(FLEX_EXECUTABLE "${BREW_FLEX_PREFIX}/bin/flex")
else()
message(FATAL_ERROR "Flex not found, to install: brew install flex")
endif()
else()
message(STATUS "Looking for flex/bison")
find_package(FLEX 2.6 REQUIRED)
find_package(BISON 2.6 REQUIRED)
endif()
# Documentation: https://cmake.org/cmake/help/latest/module/ExternalProject.html
include(ExternalProject)
# Hook for ExternalProject_Add to make sure projects build in order
function(ExternalProject_Add name)
# The DEPENDS argument is fully implicit
cmake_parse_arguments(HOOK "" "" DEPENDS ${ARGN})
if(HOOK_DEPENDS)
message(FATAL_ERROR "Explicit DEPENDS (${HOOK_DEPENDS}) not supported")
endif()
# Update the LAST_EXTERNAL_PROJECT property
get_property(LAST_EXTERNAL_PROJECT GLOBAL PROPERTY LAST_EXTERNAL_PROJECT)
set_property(GLOBAL PROPERTY LAST_EXTERNAL_PROJECT ${name})
# Pass the previous project as a dependency to this call
if(LAST_EXTERNAL_PROJECT)
set(HOOK_ARGS DEPENDS "${LAST_EXTERNAL_PROJECT}")
message(STATUS "ExternalProject: ${name} depends on ${LAST_EXTERNAL_PROJECT}")
else()
message(STATUS "ExternalProject: ${name}")
endif()
_ExternalProject_Add(${name} ${ARGN} ${HOOK_ARGS}
# Reference: https://www.scivision.dev/cmake-external-project-ninja-verbose/
USES_TERMINAL_DOWNLOAD ON
USES_TERMINAL_UPDATE ON
USES_TERMINAL_PATCH ON
USES_TERMINAL_CONFIGURE ON
USES_TERMINAL_BUILD ON
USES_TERMINAL_INSTALL ON
USES_TERMINAL_TEST ON
DOWNLOAD_EXTRACT_TIMESTAMP ON
)
endfunction()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
# Suppress warnings for clang-cl builds, some of these cause compilation errors.
list(APPEND ADDITIONAL_FLAGS "-w")
elseif(UNIX AND NOT APPLE)
# To compile shared libraries, everything needs to be compiled as position independent code when using clang on linux
list(APPEND ADDITIONAL_FLAGS "-fPIC")
endif()
endif()
# Convert a CMake list to a space-separated list
list(JOIN ADDITIONAL_FLAGS " " ADDITIONAL_FLAGS)
# Default cache variables for all projects
list(APPEND CMAKE_ARGS
"-DCMAKE_PREFIX_PATH:FILEPATH=${CMAKE_INSTALL_PREFIX};${CMAKE_PREFIX_PATH}"
"-DCMAKE_INSTALL_PREFIX:FILEPATH=${CMAKE_INSTALL_PREFIX}"
"-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
"-DBUILD_SHARED_LIBS:STRING=${BUILD_SHARED_LIBS}"
"-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}"
"-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}"
"-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${ADDITIONAL_FLAGS}"
"-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${ADDITIONAL_FLAGS}"
)
if(CMAKE_C_COMPILER_LAUNCHER)
list(APPEND CMAKE_ARGS "-DCMAKE_C_COMPILER_LAUNCHER:STRING=${CMAKE_C_COMPILER_LAUNCHER}")
endif()
if(CMAKE_CXX_COMPILER_LAUNCHER)
list(APPEND CMAKE_ARGS "-DCMAKE_CXX_COMPILER_LAUNCHER:STRING=${CMAKE_CXX_COMPILER_LAUNCHER}")
endif()
message(STATUS "Compiling all dependencies with the following CMake arguments:")
foreach(CMAKE_ARG ${CMAKE_ARGS})
message("\t${CMAKE_ARG}")
endforeach()
function(simple_git repo tag)
get_filename_component(name "${repo}" NAME_WE)
ExternalProject_Add(${name}
GIT_REPOSITORY
"${repo}"
GIT_TAG
"${tag}"
GIT_PROGRESS
ON
CMAKE_CACHE_ARGS
${CMAKE_ARGS}
${ARGN}
CMAKE_GENERATOR
"Ninja"
)
endfunction()
function(simple_submodule folder)
set(folder_path "${CMAKE_CURRENT_SOURCE_DIR}/${folder}")
if(NOT EXISTS "${folder_path}" OR NOT EXISTS "${folder_path}/CMakeLists.txt")
message(STATUS "Submodule '${folder}' not initialized, running git...")
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse --show-toplevel
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE git_root
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY
)
execute_process(
COMMAND "${GIT_EXECUTABLE}" submodule update --init
WORKING_DIRECTORY "${git_root}"
COMMAND_ERROR_IS_FATAL ANY
)
endif()
ExternalProject_Add(${folder}
SOURCE_DIR
"${folder_path}"
CMAKE_CACHE_ARGS
${CMAKE_ARGS}
${ARGN}
CMAKE_GENERATOR
"Ninja"
# Always trigger the build step (necessary because there is no download step)
BUILD_ALWAYS
ON
)
endfunction()