build.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. #!/bin/bash
  2. #-------------------------------------------------------------------------------------------------------
  3. # Copyright (C) Microsoft. All rights reserved.
  4. # Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  5. #-------------------------------------------------------------------------------------------------------
  6. SAFE_RUN() {
  7. local SF_RETURN_VALUE=$($1 2>&1)
  8. if [[ $? != 0 ]]; then
  9. >&2 echo $SF_RETURN_VALUE
  10. exit 1
  11. fi
  12. echo $SF_RETURN_VALUE
  13. }
  14. ERROR_EXIT() {
  15. if [[ $? != 0 ]]; then
  16. echo $($1 2>&1)
  17. exit 1;
  18. fi
  19. }
  20. PRINT_USAGE() {
  21. echo ""
  22. echo "[ChakraCore Build Script Help]"
  23. echo ""
  24. echo "build.sh [options]"
  25. echo ""
  26. echo "options:"
  27. echo " --arch=[*] Set target arch (x86)"
  28. echo " --cc=PATH Path to Clang (see example below)"
  29. echo " --cxx=PATH Path to Clang++ (see example below)"
  30. echo " --create-deb=V Create .deb package with given V version"
  31. echo " -d, --debug Debug build (by default Release build)"
  32. echo " --embed-icu Download and embed ICU-57 statically"
  33. echo " -h, --help Show help"
  34. echo " --icu=PATH Path to ICU include folder (see example below)"
  35. echo " -j [N], --jobs[=N] Multicore build, allow N jobs at once"
  36. echo " -n, --ninja Build with ninja instead of make"
  37. echo " --no-icu Compile without unicode/icu support"
  38. echo " --no-jit Disable JIT"
  39. echo " --lto Enables LLVM Full LTO"
  40. echo " --lto-thin Enables LLVM Thin LTO - xcode 8+ or clang 3.9+"
  41. echo " --static Build as static library (by default shared library)"
  42. echo " --sanitize=CHECKS Build with clang -fsanitize checks,"
  43. echo " e.g. undefined,signed-integer-overflow"
  44. echo " -t, --test-build Test build (by default Release build)"
  45. echo " --target[=S] Target OS"
  46. echo " --xcode Generate XCode project"
  47. echo " --without=FEATURE,FEATURE,..."
  48. echo " Disable FEATUREs from JSRT experimental"
  49. echo " features."
  50. echo " -v, --verbose Display verbose output including all options"
  51. echo ""
  52. echo "example:"
  53. echo " ./build.sh --cxx=/path/to/clang++ --cc=/path/to/clang -j"
  54. echo "with icu:"
  55. echo " ./build.sh --icu=/usr/local/opt/icu4c/include"
  56. echo ""
  57. }
  58. CHAKRACORE_DIR=`dirname $0`
  59. _CXX=""
  60. _CC=""
  61. _VERBOSE=""
  62. BUILD_TYPE="Release"
  63. CMAKE_GEN=
  64. MAKE=make
  65. MULTICORE_BUILD=""
  66. NO_JIT=
  67. ICU_PATH="-DICU_SETTINGS_RESET=1"
  68. STATIC_LIBRARY="-DSHARED_LIBRARY_SH=1"
  69. SANITIZE=
  70. WITHOUT_FEATURES=""
  71. CREATE_DEB=0
  72. ARCH="-DCC_TARGETS_AMD64_SH=1"
  73. OS_LINUX=0
  74. OS_APT_GET=0
  75. OS_UNIX=0
  76. LTO=""
  77. TARGET_OS=""
  78. if [ -f "/proc/version" ]; then
  79. OS_LINUX=1
  80. PROC_INFO=$(cat /proc/version)
  81. if [[ $PROC_INFO =~ 'Ubuntu' || $PROC_INFO =~ 'Debian'
  82. || $PROC_INFO =~ 'Linaro' ]]; then
  83. OS_APT_GET=1
  84. fi
  85. else
  86. OS_UNIX=1
  87. fi
  88. while [[ $# -gt 0 ]]; do
  89. case "$1" in
  90. --arch=*)
  91. ARCH=$1
  92. ARCH="${ARCH:7}"
  93. ;;
  94. --cxx=*)
  95. _CXX=$1
  96. _CXX=${_CXX:6}
  97. ;;
  98. --cc=*)
  99. _CC=$1
  100. _CC=${_CC:5}
  101. ;;
  102. -h | --help)
  103. PRINT_USAGE
  104. exit
  105. ;;
  106. -v | --verbose)
  107. _VERBOSE="V=1"
  108. ;;
  109. -d | --debug)
  110. BUILD_TYPE="Debug"
  111. ;;
  112. --embed-icu)
  113. if [ ! -d "${CHAKRACORE_DIR}/deps/icu/source/output" ]; then
  114. ICU_URL="http://source.icu-project.org/repos/icu/icu/tags/release-57-1"
  115. echo -e "\n----------------------------------------------------------------"
  116. echo -e "\nThis script will download ICU-LIB from\n${ICU_URL}\n"
  117. echo "It is licensed to you by its publisher, not Microsoft."
  118. echo "Microsoft is not responsible for the software."
  119. echo "Your installation and use of ICU-LIB is subject to the publisher’s terms available here:"
  120. echo -e "http://www.unicode.org/copyright.html#License\n"
  121. echo -e "----------------------------------------------------------------\n"
  122. echo "If you don't agree, press Ctrl+C to terminate"
  123. read -t 10 -p "Hit ENTER to continue (or wait 10 seconds)"
  124. SAFE_RUN `mkdir -p ${CHAKRACORE_DIR}/deps/`
  125. cd "${CHAKRACORE_DIR}/deps/";
  126. ABS_DIR=`pwd`
  127. if [ ! -d "${ABS_DIR}/icu/" ]; then
  128. echo "Downloading ICU ${ICU_URL}"
  129. if [ ! -f "/usr/bin/svn" ]; then
  130. echo -e "\nYou should install 'svn' client in order to use this feature"
  131. if [ $OS_APT_GET == 1 ]; then
  132. echo "tip: Try 'sudo apt-get install subversion'"
  133. fi
  134. exit 1
  135. fi
  136. svn export -q $ICU_URL icu
  137. ERROR_EXIT "rm -rf ${ABS_DIR}/icu/"
  138. fi
  139. cd "${ABS_DIR}/icu/source";./configure --with-data-packaging=static\
  140. --prefix="${ABS_DIR}/icu/source/output/"\
  141. --enable-static --disable-shared --with-library-bits=64\
  142. --disable-icuio --disable-layout\
  143. CXXFLAGS="-fPIC" CFLAGS="-fPIC"
  144. ERROR_EXIT "rm -rf ${ABS_DIR}/icu/source/output/"
  145. make STATICCFLAGS="-fPIC" STATICCXXFLAGS="-fPIC" STATICCPPFLAGS="-DPIC" install
  146. ERROR_EXIT "rm -rf ${ABS_DIR}/icu/source/output/"
  147. cd "${ABS_DIR}/../"
  148. fi
  149. ICU_PATH="-DCC_EMBED_ICU_SH=1"
  150. ;;
  151. -t | --test-build)
  152. BUILD_TYPE="Test"
  153. ;;
  154. -j | --jobs)
  155. if [[ "$1" == "-j" && "$2" =~ ^[^-] ]]; then
  156. MULTICORE_BUILD="-j $2"
  157. shift
  158. else
  159. MULTICORE_BUILD="-j $(nproc)"
  160. fi
  161. ;;
  162. -j=* | --jobs=*) # -j=N syntax used in CI
  163. MULTICORE_BUILD=$1
  164. if [[ "$1" =~ ^-j= ]]; then
  165. MULTICORE_BUILD="-j ${MULTICORE_BUILD:3}"
  166. else
  167. MULTICORE_BUILD="-j ${MULTICORE_BUILD:7}"
  168. fi
  169. ;;
  170. --icu=*)
  171. ICU_PATH=$1
  172. ICU_PATH="-DICU_INCLUDE_PATH_SH=${ICU_PATH:6}"
  173. ;;
  174. --lto)
  175. LTO="-DENABLE_FULL_LTO_SH=1"
  176. ;;
  177. --lto-thin)
  178. LTO="-DENABLE_THIN_LTO_SH=1"
  179. ;;
  180. -n | --ninja)
  181. CMAKE_GEN="-G Ninja"
  182. MAKE=ninja
  183. ;;
  184. --no-icu)
  185. ICU_PATH="-DNO_ICU_PATH_GIVEN_SH=1"
  186. ;;
  187. --no-jit)
  188. NO_JIT="-DNO_JIT_SH=1"
  189. ;;
  190. --xcode)
  191. CMAKE_GEN="-G Xcode -DCC_XCODE_PROJECT=1"
  192. MAKE=0
  193. ;;
  194. --create-deb=*)
  195. CREATE_DEB=$1
  196. CREATE_DEB="${CREATE_DEB:13}"
  197. ;;
  198. --static)
  199. STATIC_LIBRARY="-DSTATIC_LIBRARY_SH=1"
  200. ;;
  201. --sanitize=*)
  202. SANITIZE=$1
  203. SANITIZE=${SANITIZE:11} # value after --sanitize=
  204. SANITIZE="-DCLANG_SANITIZE_SH=${SANITIZE}"
  205. ;;
  206. --target=*)
  207. _TARGET_OS=$1
  208. _TARGET_OS="${_TARGET_OS:9}"
  209. if [[ $_TARGET_OS =~ "android" ]]; then
  210. OLD_PATH=$PATH
  211. export TOOLCHAIN=$PWD/android-toolchain-arm
  212. TARGET_OS="-DCC_TARGET_OS_ANDROID_SH=1 -DANDROID_TOOLCHAIN_DIR=${TOOLCHAIN}/arm-linux-androideabi"
  213. export PATH=$TOOLCHAIN/bin:$OLD_PATH
  214. export AR=arm-linux-androideabi-ar
  215. export CC=arm-linux-androideabi-clang
  216. export CXX=arm-linux-androideabi-clang++
  217. export LINK=arm-linux-androideabi-clang++
  218. export STRIP=arm-linux-androideabi-strip
  219. # override CXX and CC
  220. _CXX="${TOOLCHAIN}/bin/${CXX}"
  221. _CC="${TOOLCHAIN}/bin/${CC}"
  222. fi
  223. ;;
  224. --without=*)
  225. FEATURES=$1
  226. FEATURES=${FEATURES:10} # value after --without=
  227. for x in ${FEATURES//,/ } # replace comma with space then split
  228. do
  229. if [[ "$WITHOUT_FEATURES" == "" ]]; then
  230. WITHOUT_FEATURES="-DWITHOUT_FEATURES_SH="
  231. else
  232. WITHOUT_FEATURES="$WITHOUT_FEATURES;"
  233. fi
  234. WITHOUT_FEATURES="${WITHOUT_FEATURES}-DCOMPILE_DISABLE_${x}=1"
  235. done
  236. ;;
  237. *)
  238. echo "Unknown option $1"
  239. PRINT_USAGE
  240. exit -1
  241. ;;
  242. esac
  243. shift
  244. done
  245. if [[ ${#_VERBOSE} > 0 ]]; then
  246. # echo options back to the user
  247. echo "Printing command line options back to the user:"
  248. echo "_CXX=${_CXX}"
  249. echo "_CC=${_CC}"
  250. echo "BUILD_TYPE=${BUILD_TYPE}"
  251. echo "MULTICORE_BUILD=${MULTICORE_BUILD}"
  252. echo "ICU_PATH=${ICU_PATH}"
  253. echo "CMAKE_GEN=${CMAKE_GEN}"
  254. echo "MAKE=${MAKE} $_VERBOSE"
  255. echo ""
  256. fi
  257. CLANG_PATH=
  258. if [[ ${#_CXX} > 0 || ${#_CC} > 0 ]]; then
  259. if [[ ${#_CXX} == 0 || ${#_CC} == 0 ]]; then
  260. echo "ERROR: '-cxx' and '-cc' options must be used together."
  261. exit 1
  262. fi
  263. echo "Custom CXX ${_CXX}"
  264. echo "Custom CC ${_CC}"
  265. if [[ ! -f $_CXX || ! -f $_CC ]]; then
  266. echo "ERROR: Custom compiler not found on given path"
  267. exit 1
  268. fi
  269. CLANG_PATH=$_CXX
  270. else
  271. RET_VAL=$(SAFE_RUN 'c++ --version')
  272. if [[ ! $RET_VAL =~ "clang" ]]; then
  273. echo "Searching for Clang..."
  274. if [[ -f /usr/bin/clang++ ]]; then
  275. echo "Clang++ found at /usr/bin/clang++"
  276. _CXX=/usr/bin/clang++
  277. _CC=/usr/bin/clang
  278. CLANG_PATH=$_CXX
  279. else
  280. echo "ERROR: clang++ not found at /usr/bin/clang++"
  281. echo ""
  282. echo "You could use clang++ from a custom location."
  283. PRINT_USAGE
  284. exit 1
  285. fi
  286. else
  287. CLANG_PATH=c++
  288. fi
  289. fi
  290. # check clang version (min required 3.7)
  291. VERSION=$($CLANG_PATH --version | grep "version [0-9]*\.[0-9]*" --o -i | grep "[0-9]\.[0-9]*" --o)
  292. VERSION=${VERSION/./}
  293. if [[ $VERSION -lt 37 ]]; then
  294. echo "ERROR: Minimum required Clang version is 3.7"
  295. exit 1
  296. fi
  297. CC_PREFIX=""
  298. if [[ ${#_CXX} > 0 ]]; then
  299. CC_PREFIX="-DCMAKE_CXX_COMPILER=$_CXX -DCMAKE_C_COMPILER=$_CC"
  300. fi
  301. build_directory="$CHAKRACORE_DIR/BuildLinux/${BUILD_TYPE:0}"
  302. if [ ! -d "$build_directory" ]; then
  303. SAFE_RUN `mkdir -p $build_directory`
  304. fi
  305. pushd $build_directory > /dev/null
  306. if [[ $ARCH =~ "x86" ]]; then
  307. ARCH="-DCC_TARGETS_X86_SH=1"
  308. echo "Compile Target : x86"
  309. else
  310. if [[ $ARCH =~ "arm" ]]; then
  311. ARCH="-DCC_TARGETS_ARM_SH=1"
  312. echo "Compile Target : arm"
  313. else
  314. echo "Compile Target : amd64"
  315. fi
  316. fi
  317. echo Generating $BUILD_TYPE makefiles
  318. cmake $CMAKE_GEN $CC_PREFIX $ICU_PATH $LTO $STATIC_LIBRARY $ARCH $TARGET_OS \
  319. -DCMAKE_BUILD_TYPE=$BUILD_TYPE $SANITIZE $NO_JIT $WITHOUT_FEATURES ../..
  320. _RET=$?
  321. if [[ $? == 0 ]]; then
  322. if [[ $MAKE != 0 ]]; then
  323. $MAKE $MULTICORE_BUILD $_VERBOSE 2>&1 | tee build.log
  324. _RET=${PIPESTATUS[0]}
  325. else
  326. echo "Visit given folder above for xcode project file ----^"
  327. fi
  328. fi
  329. if [[ $_RET != 0 ]]; then
  330. echo "See error details above. Exit code was $_RET"
  331. else
  332. if [[ $CREATE_DEB != 0 ]]; then
  333. DEB_FOLDER=`realpath .`
  334. DEB_FOLDER="${DEB_FOLDER}/chakracore_${CREATE_DEB}"
  335. mkdir -p $DEB_FOLDER/usr/local/bin
  336. mkdir -p $DEB_FOLDER/DEBIAN
  337. cp $DEB_FOLDER/../ch $DEB_FOLDER/usr/local/bin/
  338. if [[ $STATIC_LIBRARY == "-DSHARED_LIBRARY_SH=1" ]]; then
  339. cp $DEB_FOLDER/../*.so $DEB_FOLDER/usr/local/bin/
  340. fi
  341. echo -e "Package: ChakraCore"\
  342. "\nVersion: ${CREATE_DEB}"\
  343. "\nSection: base"\
  344. "\nPriority: optional"\
  345. "\nArchitecture: amd64"\
  346. "\nDepends: libc6 (>= 2.19), uuid-dev (>> 0), libicu-dev (>> 0)"\
  347. "\nMaintainer: ChakraCore <[email protected]>"\
  348. "\nDescription: Chakra Core"\
  349. "\n Open source Core of Chakra Javascript Engine"\
  350. > $DEB_FOLDER/DEBIAN/control
  351. dpkg-deb --build $DEB_FOLDER
  352. _RET=$?
  353. if [[ $_RET == 0 ]]; then
  354. echo ".deb package is available under $build_directory"
  355. fi
  356. fi
  357. fi
  358. popd > /dev/null
  359. exit $_RET