-
Notifications
You must be signed in to change notification settings - Fork 37
/
build-external.sh
executable file
·290 lines (255 loc) · 8.42 KB
/
build-external.sh
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
281
282
283
284
285
286
287
288
289
290
#!/usr/bin/env bash
##
## BSD 3-Clause License
##
## This file is part of the RootBA project.
## https://github.com/NikolausDemmel/rootba
##
## Copyright (c) 2021-2023, Nikolaus Demmel.
## All rights reserved.
##
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
PROJECT_DIR="$SCRIPT_DIR/.."
set -x
set -e
if [ `uname -s` == Darwin ]; then
product_version=$(sw_vers -productVersion)
os_vers=( ${product_version//./ } )
os_vers_major="${os_vers[0]}"
os_vers_minor="${os_vers[1]}"
if [[ $os_vers_major == 10 && $os_vers_minor -lt 15 ]]; then
echo "ERROR: macOS before 10.15 Catalina not supported"
fi
else
# enable sized deallocation Pangolin / pybind11 needs it for C++17
# TODO: still needed??
# EXTRA_CXX_FLAGS="-fsized-deallocation"
# TODO: more flexibility when determining correct default compiler, depending on what is installed
# GCC version 9 is minimum for decent C++17 support
if [ -z "$CXX" ]; then
for VER in 9 10 11 12 13; do
if hash g++-$VER 2> /dev/null; then
export CC=gcc-$VER
export CXX=g++-$VER
break
fi
done
fi
# if no GCC, try clang; minimum version is 9
if [ -z "$CXX" ]; then
for VER in 9 10 11 12 13 14 15 16 17; do
if hash clang++-$VER 2> /dev/null; then
export CC=clang-$VER
export CXX=clang++-$VER
break
fi
done
fi
fi
# check that compiler can be found if set
if [ -n "$CXX" ]; then
which "$CXX"
fi
if [ -n "$CC" ]; then
which "$CC"
fi
BUILD_TYPE="${1:-Release}"
# build all external dependencies with the same standard
# TODO: build all externals from withing cmake (external_project_add)
# 1. this ensures the actual correct parameters are used
# 2. it allows to use multiple parallel builds with different settings
ROOTBA_CXX_STANDARD=17
# number of logical cores on linux and macos
NUM_CORES=`(which nproc > /dev/null && nproc) || sysctl -n hw.logicalcpu || echo 1`
#NUM_CORES=1
NUM_PARALLEL_BUILDS=$NUM_CORES
EIGEN_DIR="$PROJECT_DIR/external/eigen"
# Important note on Eigen alignment and the arch flag. TLDR: Passing
# arch=native for all build types is currently the only viable option
# to avoid suble bugs with Eigen.
#
# Eigen uses 16 byte alignemnt by default, but switches to 32 byte
# alignment if AVX instructions are enabled. This is the case on
# modern Intel hardware if we pass arch=native. It is vital to ensure
# that all translation units, including all thirdparty libraries, use
# the same value for EIGEN_MAX_ALIGN_BYTES (see
# https://eigen.tuxfamily.org/dox/TopicPreprocessorDirectives.html),
# since the aliged-malloc functions provided by Eigen might not be
# inlined and thus be taken from any of the translation units. Our
# current approach is to ensure arch=native everywhere. A possible
# alternative would be to explicitly pass -DEIGEN_MAX_ALIGN_BYTES=32
# everywhere, then 32 bytes would be used regardless of whether avx is
# enabled or not.
#
# Note that Ceres might override with arch=native in Release mode no
# matter what we pass it and OpenGV overwrites to always build in
# release mode and use arch=native, so any other value for CXX_MARCH
# might not work as expected. Also, even though we explicitly pass
# -O3, it might be overwritten e.g. with -O2 if we don't also set the
# build type to Release.
# NOTE: Newer versions of Clang / AppleClang support -march=native on Apple Silicon,
# so at some point we can remove this workaround.
if [ "$(uname -m)" = "x86_64" ]; then
CXX_MARCH="${CXX_MARCH:-native}"
fi
# TODO: On apple silicon check compiler version, then set to "march native" if supported.
# Same also in build-rootba.sh and main CMakeLists.txt
if [ ! -z "$CXX_MARCH" ]; then
EXTRA_CXX_FLAGS="$EXTRA_CXX_FLAGS -march=$CXX_MARCH"
fi
# map ci-build types to Default with custom flags to avoid override of -g0
if [[ "${BUILD_TYPE}" == Ci* ]]; then
if [[ "${BUILD_TYPE}" == CiRelWithDebInfo ]]; then
EXTRA_CXX_FLAGS="$EXTRA_CXX_FLAGS -g0 -O3"
elif [[ "${BUILD_TYPE}" == CiDebug ]]; then
EXTRA_CXX_FLAGS="$EXTRA_CXX_FLAGS -g0"
else
echo "Unknown build type $BUILD_TYPE."
exit 1
fi
BUILD_TYPE=Default
elif ! [[ "${BUILD_TYPE}" == *Debug ]]; then
EXTRA_CXX_FLAGS="$EXTRA_CXX_FLAGS -O3"
fi
if [[ "${BUILD_TYPE}" == Sanitizer* ]]; then
EXTRA_CXX_FLAGS="$EXTRA_CXX_FLAGS -g0 -fno-omit-frame-pointer -fsanitize=address"
EXTRA_LINKER_FLAGS="$EXTRA_LINKER_FLAGS -fno-omit-frame-pointer -fsanitize=address"
BUILD_TYPE=${BUILD_TYPE#Sanitizer}
fi
# TODO: check if needed
# avoid countless warnings on GCC9 (clang always outputs 4.2.1 for -dumpversion)
#if [ -n "$CXX" ] && $CXX -v 2>&1 | grep 'gcc version' > /dev/null; then
# EXTRA_CXX_FLAGS="${EXTRA_CXX_FLAGS} -Wno-deprecated-copy"
#fi
# respect CXXFLAGS environment variable
EXTRA_CXX_FLAGS="${EXTRA_CXX_FLAGS} ${CXXFLAGS}"
EXTERNAL_BUILD_DIR_SUFFIX=""
if [ -n "$ROOTBA_ARCH_SUFFIX" ]; then
EXTERNAL_BUILD_DIR_SUFFIX=-$ROOTBA_ARCH_SUFFIX
fi
cd "$PROJECT_DIR"
INSTALL_PREFIX="$PWD/external/install$EXTERNAL_BUILD_DIR_SUFFIX"
BUILD_EIGEN=external/build$EXTERNAL_BUILD_DIR_SUFFIX/eigen
BUILD_PANGOLIN=external/build$EXTERNAL_BUILD_DIR_SUFFIX/Pangolin
BUILD_CEREAL=external/build$EXTERNAL_BUILD_DIR_SUFFIX/cereal
BUILD_FMT=external/build$EXTERNAL_BUILD_DIR_SUFFIX/fmt
BUILD_ABSEIL=external/build$EXTERNAL_BUILD_DIR_SUFFIX/abseil-cpp
BUILD_CERES=external/build$EXTERNAL_BUILD_DIR_SUFFIX/ceres-solver
COMMON_CMAKE_ARGS=(
-DCMAKE_BUILD_TYPE=${BUILD_TYPE}
-DCMAKE_CXX_FLAGS="$EXTRA_CXX_FLAGS"
-DCMAKE_EXE_LINKER_FLAGS="$EXTRA_LINKER_FLAGS"
-DCMAKE_SHARED_LINKER_FLAGS="$EXTRA_LINKER_FLAGS"
-DCMAKE_CXX_STANDARD=$ROOTBA_CXX_STANDARD
-DCMAKE_CXX_EXTENSIONS=OFF
-DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_INSTALL_PREFIX="$INSTALL_PREFIX"
-DCMAKE_PREFIX_PATH="$INSTALL_PREFIX"
)
# check if ccache is available
if command -v ccache >/dev/null 2>&1; then
echo "Found ccache: `command -v ccache`"
COMMON_CMAKE_ARGS=(
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
"${COMMON_CMAKE_ARGS[@]}"
)
else
echo "Didn't find ccache. Compiling without."
fi
# TODO: configure shallow clone...
git submodule sync --recursive
git submodule update --init --recursive
#export VERBOSE=1
rm -rf "$INSTALL_PREFIX"
mkdir -p "$INSTALL_PREFIX"
##############################################
## Eigen
if true; then
#if false; then
rm -rf "$BUILD_EIGEN"
mkdir -p "$BUILD_EIGEN"
pushd "$BUILD_EIGEN"
cmake ../../eigen "${COMMON_CMAKE_ARGS[@]}" \
-DBUILD_TESTING=OFF
make -j$NUM_PARALLEL_BUILDS
make install
popd
fi
##############################################
## Pangolin
if true; then
#if false; then
rm -rf "$BUILD_PANGOLIN"
mkdir -p "$BUILD_PANGOLIN"
pushd "$BUILD_PANGOLIN"
cmake ../../Pangolin "${COMMON_CMAKE_ARGS[@]}" \
-DCMAKE_FIND_FRAMEWORK=LAST \
-DBUILD_EXAMPLES=OFF \
-DBUILD_TOOLS=OFF \
-DBUILD_TESTS=OFF \
-DBUILD_PANGOLIN_PYTHON=OFF \
-DBUILD_PANGOLIN_LIBOPENEXR=OFF
# Note: Now we install Eigen and it provides a config module
# "-DEIGEN_INCLUDE_DIR=$EIGEN_DIR"
make -j$NUM_PARALLEL_BUILDS all
make install
popd
fi
##############################################
## Cereal
if true; then
#if false; then
rm -rf "$BUILD_CEREAL"
mkdir -p "$BUILD_CEREAL"
pushd "$BUILD_CEREAL"
cmake ../../cereal "${COMMON_CMAKE_ARGS[@]}" \
-DJUST_INSTALL_CEREAL=ON
make -j$NUM_PARALLEL_BUILDS
make install
popd
fi
##############################################
## {fmt}
if true; then
#if false; then
rm -rf "$BUILD_FMT"
mkdir -p "$BUILD_FMT"
pushd "$BUILD_FMT"
cmake ../../fmt "${COMMON_CMAKE_ARGS[@]}" \
-DFMT_DOC=Off \
-DFMT_TEST=Off
make -j$NUM_PARALLEL_BUILDS
make install
popd
fi
##############################################
## Abseil
if true; then
#if false; then
rm -rf "$BUILD_ABSEIL"
mkdir -p "$BUILD_ABSEIL"
pushd "$BUILD_ABSEIL"
cmake ../../abseil-cpp "${COMMON_CMAKE_ARGS[@]}"
make -j$NUM_PARALLEL_BUILDS
make install
popd
fi
##############################################
## Ceres
if true; then
#if false; then
rm -rf "$BUILD_CERES"
mkdir -p "$BUILD_CERES"
pushd "$BUILD_CERES"
cmake ../../ceres-solver "${COMMON_CMAKE_ARGS[@]}" \
-DBUILD_EXAMPLES=OFF \
-DBUILD_TESTING=OFF \
-DBUILD_BENCHMARKS=OFF \
-DEXPORT_BUILD_DIR=OFF
make -j$NUM_PARALLEL_BUILDS ceres
make install
popd
fi