linux-build.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. #!/usr/bin/env bash
  2. # build-linux.sh v2.26 (c)2013-2024 Henri Beauchamp.
  3. # Released under the GPL license. https://www.gnu.org/licenses/gpl-3.0.txt
  4. export LANG=C
  5. COMMAND_LINE="$*"
  6. SCRIPTSRC=`readlink -f "$0" || echo "$0"`
  7. RUN_PATH=`dirname "$SCRIPTSRC" || echo .`
  8. cd "$RUN_PATH"
  9. function has_option()
  10. {
  11. echo "$COMMAND_LINE" | grep "\-$1" &>/dev/null
  12. return $?
  13. }
  14. function has_exec()
  15. {
  16. which "$1" &>/dev/null
  17. return $?
  18. }
  19. GCC=""
  20. GXX=""
  21. function find_gcc()
  22. {
  23. for i in $1".9" $1".8" $1".7" $1".6" $1".5" $1".4" $1".3" $1".2" $1".1" $1".0" $1 ; do
  24. if has_exec "gcc-$i" && has_exec "g++-$i" ; then
  25. echo "Will use gcc/g++ v$i to build the viewer"
  26. GCC="gcc-$i"
  27. GXX="g++-$i"
  28. return
  29. fi
  30. if has_exec "gcc$i" && has_exec "g++$i" ; then
  31. echo "Will use gcc/g++ v$i to build the viewer"
  32. GCC="gcc$i"
  33. GXX="g++$i"
  34. return
  35. fi
  36. done
  37. GCC=""
  38. GXX=""
  39. }
  40. PYTHON=""
  41. function find_python()
  42. {
  43. for i in "python3.13" "python3.12" "python3.11" "python3.10" "python3.9" "python3.8" "python3.7" "python3.6" "python3.5" "python3.4" "python3.3" "python3" "python"; do
  44. PYTHON=`which $i 2>/dev/null`
  45. if [ "$PYTHON" != "" ] && [ -x "$PYTHON" ] ; then
  46. return
  47. fi
  48. done
  49. PYTHON=""
  50. }
  51. if has_option "h" ; then
  52. echo "Usage: $0 [-option|--long-build-option...]|[-z|--zap]|[-h|--help]"
  53. echo "With -v6.N : use gcc v6.N (with N=0 to 5) if possible/found."
  54. echo " -v7.N : use gcc v7.N (with N=0 to 5) if possible/found."
  55. echo " -v8.N : use gcc v8.N (with N=0 to 5) if possible/found."
  56. echo " -v9.N : use gcc v9.N (with N=0 to 5) if possible/found."
  57. echo " -v10.N : use gcc v10.N (with N=0 to 4) if possible/found."
  58. echo " -v11.N : use gcc v11.N (with N=0 to 4) if possible/found."
  59. echo " -v12.N : use gcc v12.N (with N=0 to 4) if possible/found."
  60. echo " -v13.N : use gcc v13.N (with N=0 to 3) if possible/found."
  61. echo " -v14.N : use gcc v14.N (with N=0 or 1) if possible/found."
  62. echo " -c, --clang : use clang (if found) instead of gcc."
  63. echo " -i, --ignore-warnings : do not treat compiler warnings as errors."
  64. echo " -t, --tune : tune the optimizations for the build system CPU."
  65. echo " -l, --lto : use the link time optimization (not supported by all compilers)."
  66. echo " --protect-stack : use canaries to protect from stack overflows (slower code)."
  67. echo " --no-exec-stack : ask gcc not to make stack executable (WARNING: highly experimental)."
  68. echo " -o, --openmp : enable OpenMP optimizations (WARNING: highly experimental)."
  69. echo " -n, --ninja : use ninja (if found) to build instead of make."
  70. echo " --unity-build : use cmake UNITY_BUILD for faster compilation (WARNING: highly experimental)."
  71. echo " -d, --debug : build the Debug viewer binary instead of Release."
  72. echo " -s, --symbols : build with debugging symbols (RelWithDebInfo viewer binary)."
  73. echo " --tracy : enable Tracy profiling support (for devel builds only)."
  74. echo " -g, --gprof : enable gprof profiling (for devel builds only)."
  75. echo " -a, --asan : enable ASAN sanitizing (for devel builds only)."
  76. echo " -u, --usesystemlibs : use system libs instead of pre-built ones where possible."
  77. echo " -p, --patches : apply patches held inside ~/.secondlife/patches/cool_vl_viewer/"
  78. echo " -z, --zap : cleanup the source tree, removing any former build and library."
  79. echo " -h, --help : this help..."
  80. exit 0
  81. fi
  82. if ! [ -x scripts/develop.py ] ; then
  83. echo
  84. echo "This script must be ran from the linden/ Cool VL Viewer sources directory !".
  85. exit 1
  86. fi
  87. if has_option "z" ; then
  88. # Possible *.orig or *~ files produced during patching
  89. if [ -f applied_patches.txt ] ; then
  90. find . -name "*~" -exec rm -f {} \;
  91. find . -name "*.orig" -exec rm -f {} \;
  92. fi
  93. # Link to system python
  94. rm -f python
  95. # Compiled binaries
  96. rm -rf viewer-linux-*
  97. # Pre-built libraries and includes
  98. rm -rf bin docs include lib LICENSES autobuild-package.xml
  99. rm -f installed.xml
  100. # Static data, textures, icons and fonts
  101. rm -rf indra/newview/app_settings/dictionaries/ indra/newview/app_settings/windlight/
  102. rm -rf indra/newview/cursors_mac/ indra/newview/res-sdl/
  103. rm -f indra/newview/character/*.llm
  104. rm -f indra/newview/character/*.tga
  105. rm -rf indra/newview/character/anims/
  106. for i in indra/newview/res/*.BMP;do echo -n >$i;done
  107. for i in indra/newview/res/*.cur;do echo -n >$i;done
  108. for i in indra/newview/res/*.ico;do echo -n >$i;done
  109. rm -f indra/newview/res/*.png
  110. rm -rf indra/newview/fonts/
  111. rm -f indra/newview/cool_vl_viewer.icns
  112. # Skin textures
  113. find indra/newview/skins/ -name "*.png" -exec rm -f {} \;
  114. find indra/newview/skins/ -name "*.tga" -exec rm -f {} \;
  115. find indra/newview/skins/ -name "*.j2c" -exec rm -f {} \;
  116. # Build stuff
  117. find . -type d -name ".distcc" -exec rm -rf {} \; &>/dev/null
  118. echo "Source tree cleaned-up."
  119. exit 0
  120. fi
  121. arch=`uname -m`
  122. if [ "$arch" == "i386" ] || [ "$arch" == "i486" ] || [ "$arch" == "i586" ] || [ "$arch" == "i686" ] ; then
  123. echo "Sorry, the viewer can only be built for 64 bits targets !"
  124. exit 1
  125. fi
  126. # Deal now with long --options that could be interpreted as/collide with short
  127. # ones (this is due to our crude options parsing), and remove them from the
  128. # command line when dealt with...
  129. PROFILE=""
  130. if has_option "-tracy" ; then
  131. PROFILE="-DTRACY:BOOL=TRUE"
  132. COMMAND_LINE=${COMMAND_LINE//--tracy/}
  133. fi
  134. STACK_OPTIONS=""
  135. if has_option "-protect-stack" ; then
  136. STACK_OPTIONS="-DPROTECTSTACK:BOOL=TRUE"
  137. COMMAND_LINE=${COMMAND_LINE//--protect-stack/}
  138. fi
  139. if has_option "-no-exec-stack" ; then
  140. STACK_OPTIONS="$STACK_OPTIONS -DNOEXECSTACK:BOOL=TRUE"
  141. COMMAND_LINE=${COMMAND_LINE//--no-exec-stack/}
  142. fi
  143. UNITYBUILD=""
  144. if has_option "-unity-build" ; then
  145. UNITYBUILD="-DUSEUNITYBUILD:BOOL=TRUE"
  146. COMMAND_LINE=${COMMAND_LINE//--unity-build/}
  147. fi
  148. BUILD_TYPE="Release"
  149. PACKAGE_DIR="viewer-linux-$arch-release"
  150. echo "==============================================================================="
  151. if has_option "d" ; then
  152. BUILD_TYPE="Debug"
  153. PACKAGE_DIR="viewer-linux-$arch-debug"
  154. elif has_option "s" ; then
  155. BUILD_TYPE="RelWithDebInfo"
  156. PACKAGE_DIR="viewer-linux-$arch-relwithdebinfo"
  157. fi
  158. echo "Building a $BUILD_TYPE viewer."
  159. if [ "$arch" == "aarch64" ] ; then
  160. arch="arm64"
  161. fi
  162. echo "Building for architecture: $arch"
  163. find_python
  164. if [ "$PYTHON" != "" ] ; then
  165. ln -sf "$PYTHON" "$RUN_PATH/python"
  166. export PATH="$RUN_PATH:$PATH"
  167. echo "Forcing the use of python interpreter: $PYTHON"
  168. else
  169. echo "ERROR: could not find a compatible Python interpreter. Please install Python version 3.9 to 3.3."
  170. exit 1
  171. fi
  172. if has_option "v[16-9]" ; then
  173. if has_option "v6\.0" ; then
  174. find_gcc "6.0"
  175. elif has_option "v6\.1" ; then
  176. find_gcc "6.1"
  177. elif has_option "v6\.2" ; then
  178. find_gcc "6.2"
  179. elif has_option "v6\.3" ; then
  180. find_gcc "6.3"
  181. elif has_option "v6\.4" ; then
  182. find_gcc "6.4"
  183. elif has_option "v6\.5" ; then
  184. find_gcc "6.5"
  185. elif has_option "v7\.0" ; then
  186. find_gcc "7.0"
  187. elif has_option "v7\.1" ; then
  188. find_gcc "7.1"
  189. elif has_option "v7\.2" ; then
  190. find_gcc "7.2"
  191. elif has_option "v7\.3" ; then
  192. find_gcc "7.3"
  193. elif has_option "v7\.4" ; then
  194. find_gcc "7.4"
  195. elif has_option "v7\.5" ; then
  196. find_gcc "7.5"
  197. elif has_option "v8\.0" ; then
  198. find_gcc "8.0"
  199. elif has_option "v8\.1" ; then
  200. find_gcc "8.1"
  201. elif has_option "v8\.2" ; then
  202. find_gcc "8.2"
  203. elif has_option "v8\.3" ; then
  204. find_gcc "8.3"
  205. elif has_option "v8\.4" ; then
  206. find_gcc "8.4"
  207. elif has_option "v8\.5" ; then
  208. find_gcc "8.5"
  209. elif has_option "v9\.0" ; then
  210. find_gcc "9.0"
  211. elif has_option "v9\.1" ; then
  212. find_gcc "9.1"
  213. elif has_option "v9\.2" ; then
  214. find_gcc "9.2"
  215. elif has_option "v9\.3" ; then
  216. find_gcc "9.3"
  217. elif has_option "v9\.4" ; then
  218. find_gcc "9.4"
  219. elif has_option "v9\.5" ; then
  220. find_gcc "9.5"
  221. elif has_option "v10\.0" ; then
  222. find_gcc "10.0"
  223. elif has_option "v10\.1" ; then
  224. find_gcc "10.1"
  225. elif has_option "v10\.2" ; then
  226. find_gcc "10.2"
  227. elif has_option "v10\.3" ; then
  228. find_gcc "10.3"
  229. elif has_option "v10\.4" ; then
  230. find_gcc "10.4"
  231. elif has_option "v11\.0" ; then
  232. find_gcc "11.0"
  233. elif has_option "v11\.1" ; then
  234. find_gcc "11.1"
  235. elif has_option "v11\.2" ; then
  236. find_gcc "11.2"
  237. elif has_option "v11\.3" ; then
  238. find_gcc "11.3"
  239. elif has_option "v11\.4" ; then
  240. find_gcc "11.3"
  241. elif has_option "v12\.0" ; then
  242. find_gcc "12.0"
  243. elif has_option "v12\.1" ; then
  244. find_gcc "12.1"
  245. elif has_option "v12\.2" ; then
  246. find_gcc "12.2"
  247. elif has_option "v12\.3" ; then
  248. find_gcc "12.3"
  249. elif has_option "v12\.4" ; then
  250. find_gcc "12.4"
  251. elif has_option "v13\.0" ; then
  252. find_gcc "13.0"
  253. elif has_option "v13\.1" ; then
  254. find_gcc "13.1"
  255. elif has_option "v13\.2" ; then
  256. find_gcc "13.2"
  257. elif has_option "v13\.3" ; then
  258. find_gcc "13.3"
  259. elif has_option "v14\.0" ; then
  260. find_gcc "14.0"
  261. elif has_option "v14\.1" ; then
  262. find_gcc "14.1"
  263. fi
  264. elif has_option "c" ; then
  265. if has_exec "clang" && has_exec "clang++" ; then
  266. clang_version1=`clang --version`
  267. clang_version2=`echo $clang_version1 | cut -d ' ' -f 3`
  268. echo "Will use clang/clang++ version $clang_version2 to build the viewer"
  269. GCC="clang"
  270. GXX="clang++"
  271. fi
  272. fi
  273. if [ "$GXX" != "" ] ; then
  274. GCC="-DCMAKE_C_COMPILER=$GCC"
  275. GXX="-DCMAKE_CXX_COMPILER=$GXX"
  276. fi
  277. NO_FATAL_WARNINGS=""
  278. if has_option "i" ; then
  279. NO_FATAL_WARNINGS="-DNO_FATAL_WARNINGS:BOOL=TRUE"
  280. echo "The compiler warnings will not be treated as errors."
  281. fi
  282. TUNE_FLAGS=""
  283. if has_option "t" ; then
  284. TUNE_FLAGS="-march=native"
  285. echo "Compiling with native system CPU optimizations."
  286. fi
  287. LTO=""
  288. if has_option "l" ; then
  289. # Note: LINK_JOBS is used in indra/cmake/Linking.cmake to specify the
  290. # number of plugin jobs to use by ld, when using clang to compile the
  291. # viewer; we use as many jobs as we got virtual cores (failing to specify
  292. # it for clang would cause ld to use the number of physical cores for the
  293. # number of jobs, meaning SMT processors would be only half loaded).
  294. LTO="-DUSELTO:BOOL=TRUE -DLINK_JOBS=`grep processor /proc/cpuinfo | wc -l`"
  295. echo "Compiling with link-time optimizations (LTO)."
  296. fi
  297. OPENMP=""
  298. if has_option "o" ; then
  299. OPENMP="-DOPENMP:BOOL=TRUE"
  300. echo "Compiling with OpenMP optimizations (WARNING: highly experimental)."
  301. fi
  302. if [ "$PROFILE" != "" ] ; then
  303. echo "Compiling with Tracy profiler support (relevant only to devel builds)."
  304. fi
  305. if has_option "g" ; then
  306. PROFILE="$PROFILE -DGPROF:BOOL=TRUE"
  307. echo "Compiling with gprof profiling (WARNING: slow viewer, for devel builds only)."
  308. fi
  309. if has_option "a" ; then
  310. PROFILE="$PROFILE -DASAN:BOOL=TRUE"
  311. echo "Compiling with ASAN sanitizing (WARNING: slow viewer, for devel builds only)."
  312. fi
  313. GENERATOR=""
  314. if has_option "n" && has_exec "ninja" ; then
  315. GENERATOR="-G Ninja"
  316. echo "Using ninja to build instead of make."
  317. # Note: ninja fails to notice the dependency with the pre-built library
  318. # downloads when looking for some static libraries... This might also be a
  319. # bug in the cmake generator for ninja. Here is a HACK to make ninja happy:
  320. LIBDIR="$RUN_PATH/lib/release"
  321. if ! [ -d "$LIBDIR" ] ; then
  322. mkdir -p "$LIBDIR"
  323. touch "$LIBDIR/libcef_dll_wrapper.a"
  324. touch "$LIBDIR/libdullahan.a"
  325. touch "$LIBDIR/libcef.so"
  326. touch "$LIBDIR/libminizip.a"
  327. touch "$LIBDIR/libxml2.a"
  328. touch "$LIBDIR/libpcrecpp.a"
  329. touch "$LIBDIR/libpcre.a"
  330. touch "$LIBDIR/liblua.a"
  331. touch "$LIBDIR/libz.a"
  332. touch "$LIBDIR/mimalloc.o"
  333. fi
  334. fi
  335. USESYSTEMLIBS=""
  336. if has_option "u" ; then
  337. USESYSTEMLIBS="--systemlibs"
  338. echo "Using system libraries instead of pre-built ones when possible."
  339. fi
  340. PATCH_DIR="$HOME/.secondlife/patches/cool_vl_viewer"
  341. if has_option "p" ; then
  342. if [ -d "$PATCH_DIR" ] && ! [ -f applied_patches.txt ] ; then
  343. PATCHES=`/bin/ls $PATCH_DIR/*.patch* 2>/dev/null`
  344. if [ "$PATCHES" != "" ] ; then
  345. echo "Applying patches from $PATCH_DIR:"
  346. for i in $PATCHES; do
  347. echo " - Patch: $i"
  348. if echo $i | grep ".gz" &>/dev/null ; then
  349. gzip -cd $i | patch -p1 -s
  350. elif echo $i | grep ".bz2" &>/dev/null ; then
  351. bzip2 -cd $i | patch -p1 -s
  352. elif echo $i | grep ".xz" &>/dev/null ; then
  353. xz -cd $i | patch -p1 -s
  354. else
  355. patch -p1 -s <$i
  356. fi
  357. echo "$i" >>applied_patches.txt
  358. done
  359. fi
  360. fi
  361. fi
  362. echo "==============================================================================="
  363. start=`date +%s%2N`
  364. if [ "$TUNE_FLAGS" != "" ] ; then
  365. ./scripts/develop.py $USESYSTEMLIBS $GENERATOR -t $BUILD_TYPE configure $GCC $GXX $NO_FATAL_WARNINGS $STACK_OPTIONS $OPENMP $LTO $UNITYBUILD $PROFILE \
  366. -DCMAKE_C_FLAGS:STRING="$TUNE_FLAGS" \
  367. -DCMAKE_CXX_FLAGS:STRING="$TUNE_FLAGS" \
  368. -DCMAKE_CXX_FLAGS_RELEASE:STRING="$TUNE_FLAGS"
  369. else
  370. ./scripts/develop.py $USESYSTEMLIBS $GENERATOR -t $BUILD_TYPE configure $GCC $GXX $NO_FATAL_WARNINGS $STACK_OPTIONS $OPENMP $LTO $UNITYBUILD $PROFILE
  371. fi
  372. ./scripts/develop.py $USESYSTEMLIBS $GENERATOR -t $BUILD_TYPE build
  373. if (( $? != 0 )) ; then
  374. exit 1
  375. fi
  376. now=`date +%s%2N`
  377. FINAL_DIR=`pwd`"/$PACKAGE_DIR/newview"
  378. if [ -x "$FINAL_DIR/CoolVLViewer" ] ; then
  379. echo "==============================================================================="
  380. let delay=$now-$start
  381. let seconds=$delay/100
  382. let decimal=$delay-$seconds*100
  383. if (( $decimal < 10 )) ; then
  384. decimal="0$decimal"
  385. fi
  386. echo "Build successful. Total time taken by the building and packaging: $seconds.$decimal seconds."
  387. RUN_DIR=`find $FINAL_DIR -type d -name "CoolVLViewer-$arch*"`
  388. echo "Ready to run viewer available in : $RUN_DIR/"
  389. echo "Installation tarball available in: $FINAL_DIR/"
  390. echo "==============================================================================="
  391. else
  392. exit 1
  393. fi