mingw-w64-build 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. #!/bin/bash
  2. #
  3. # Copyright (C) 2024 Kyle Schwarz <zeranoe@gmail.com>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #
  18. ROOT_PATH="/opt/mingw"
  19. MINGW_W64_BRANCH="master"
  20. BINUTILS_BRANCH="binutils-2_42-branch"
  21. GCC_BRANCH="releases/gcc-12"
  22. ENABLE_THREADS="--enable-threads=posix"
  23. JOB_COUNT=$(($(getconf _NPROCESSORS_ONLN) + 2))
  24. LINKED_RUNTIME="msvcrt"
  25. show_help()
  26. {
  27. cat <<EOF
  28. Usage:
  29. $0 [options] <arch>...
  30. Archs:
  31. i586 Windows 32-bit for old CPUs (Intel Pentium (MMX), AMD K5, K6, K6-2, K6-III)
  32. i686 Windows 32-bit (Intel P6 [Pentium Pro], AMD K7 and newer)
  33. x86_64 Windows 64-bit
  34. Options:
  35. -h, --help show help
  36. -j <count>, --jobs <count> override make job count (default: $JOB_COUNT)
  37. -p <path>, --prefix <path> install location (default: $ROOT_PATH/<arch>)
  38. -r <path>, --root <path> location for sources, build artifacts and the resulting compiler (default: $ROOT_PATH)
  39. --keep-artifacts don't remove source and build files after a successful build
  40. --disable-threads disable pthreads and STL <thread>
  41. --cached-sources use existing sources instead of downloading new ones
  42. --binutils-branch <branch> set Binutils branch (default: $BINUTILS_BRANCH)
  43. --gcc-branch <branch> set GCC branch (default: $GCC_BRANCH)
  44. --mingw-w64-branch <branch> set MinGW-w64 branch (default: $MINGW_W64_BRANCH)
  45. --linked-runtime <runtime> set MinGW Linked Runtime (default: $LINKED_RUNTIME)
  46. EOF
  47. }
  48. error_exit()
  49. {
  50. local error_msg="$1"
  51. shift 1
  52. if [ "$error_msg" ]; then
  53. printf "%s\n" "$error_msg" >&2
  54. else
  55. printf "an error occured\n" >&2
  56. fi
  57. exit 1
  58. }
  59. arg_error()
  60. {
  61. local error_msg="$1"
  62. shift 1
  63. error_exit "$error_msg, see --help for options" "$error_msg"
  64. }
  65. execute()
  66. {
  67. local info_msg="$1"
  68. local error_msg="$2"
  69. shift 2
  70. if [ ! "$error_msg" ]; then
  71. error_msg="error"
  72. fi
  73. if [ "$info_msg" ]; then
  74. printf "(%d/%d): %s\n" "$CURRENT_STEP" "$TOTAL_STEPS" "$info_msg"
  75. CURRENT_STEP=$((CURRENT_STEP + 1))
  76. fi
  77. "$@" >>"$LOG_FILE" 2>&1 || error_exit "$error_msg, check $LOG_FILE for details"
  78. }
  79. create_dir()
  80. {
  81. local path="$1"
  82. shift 1
  83. execute "" "unable to create directory '$path'" \
  84. mkdir -p "$path"
  85. }
  86. remove_path()
  87. {
  88. local path="$1"
  89. shift 1
  90. execute "" "unable to remove path '$path'" \
  91. rm -fr "$path"
  92. }
  93. change_dir()
  94. {
  95. local path="$1"
  96. shift 1
  97. execute "" "unable to cd to directory '$path'" \
  98. cd "$path"
  99. }
  100. download_sources()
  101. {
  102. remove_path "$SRC_PATH"
  103. create_dir "$SRC_PATH"
  104. change_dir "$SRC_PATH"
  105. execute "downloading MinGW-w64 source" "" \
  106. git clone --depth 1 -b "$MINGW_W64_BRANCH" \
  107. https://git.code.sf.net/p/mingw-w64/mingw-w64 mingw-w64
  108. execute "downloading Binutils source" "" \
  109. git clone --depth 1 -b "$BINUTILS_BRANCH" \
  110. https://sourceware.org/git/binutils-gdb.git binutils
  111. execute "downloading GCC source" "" \
  112. git clone --depth 1 -b "$GCC_BRANCH" \
  113. https://gcc.gnu.org/git/gcc.git gcc
  114. execute "downloading config.guess" "" \
  115. curl -o config.guess \
  116. "https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD"
  117. }
  118. build()
  119. {
  120. local arch="$1"
  121. local prefix="$2"
  122. shift 2
  123. local bld_path="$BLD_PATH/$arch"
  124. local host="$arch-w64-mingw32"
  125. export PATH="$prefix/bin:$PATH"
  126. remove_path "$bld_path"
  127. # don't remove a user defined prefix (could be /usr/local)
  128. if [ ! "$PREFIX" ]; then
  129. remove_path "$prefix"
  130. fi
  131. if [ "$arch" = "i586" ] || [ "$arch" = "i686" ]; then
  132. local x86_dwarf2="--disable-sjlj-exceptions --with-dwarf2"
  133. local crt_lib="--enable-lib32 --disable-lib64"
  134. else
  135. local x86_dwarf2=""
  136. local crt_lib="--enable-lib64 --disable-lib32"
  137. fi
  138. create_dir "$bld_path/binutils"
  139. change_dir "$bld_path/binutils"
  140. execute "($arch): configuring Binutils" "" \
  141. "$SRC_PATH/binutils/configure" --prefix="$prefix" --disable-shared \
  142. --enable-static --with-sysroot="$prefix" --target="$host" \
  143. --disable-multilib --disable-nls --enable-lto --disable-gdb
  144. execute "($arch): building Binutils" "" \
  145. make -j $JOB_COUNT
  146. execute "($arch): installing Binutils" "" \
  147. make install
  148. create_dir "$bld_path/mingw-w64-headers"
  149. change_dir "$bld_path/mingw-w64-headers"
  150. execute "($arch): configuring MinGW-w64 headers" "" \
  151. "$SRC_PATH/mingw-w64/mingw-w64-headers/configure" --build="$BUILD" \
  152. --host="$host" --prefix="$prefix/$host" \
  153. --with-default-msvcrt=$LINKED_RUNTIME
  154. execute "($arch): installing MinGW-w64 headers" "" \
  155. make install
  156. create_dir "$bld_path/gcc"
  157. change_dir "$bld_path/gcc"
  158. execute "($arch): configuring GCC" "" \
  159. "$SRC_PATH/gcc/configure" --target="$host" --disable-shared \
  160. --enable-static --disable-multilib --prefix="$prefix" \
  161. --enable-languages=c,c++ --disable-nls $ENABLE_THREADS \
  162. $x86_dwarf2
  163. execute "($arch): building GCC (all-gcc)" "" \
  164. make -j $JOB_COUNT all-gcc
  165. execute "($arch): installing GCC (install-gcc)" "" \
  166. make install-gcc
  167. create_dir "$bld_path/mingw-w64-crt"
  168. change_dir "$bld_path/mingw-w64-crt"
  169. execute "($arch): configuring MinGW-w64 CRT" "" \
  170. "$SRC_PATH/mingw-w64/mingw-w64-crt/configure" --build="$BUILD" \
  171. --host="$host" --prefix="$prefix/$host" \
  172. --with-default-msvcrt=$LINKED_RUNTIME \
  173. --with-sysroot="$prefix/$host" $crt_lib
  174. execute "($arch): building MinGW-w64 CRT" "" \
  175. make -j $JOB_COUNT
  176. execute "($arch): installing MinGW-w64 CRT" "" \
  177. make install
  178. if [ "$ENABLE_THREADS" ]; then
  179. create_dir "$bld_path/mingw-w64-winpthreads"
  180. change_dir "$bld_path/mingw-w64-winpthreads"
  181. execute "($arch): configuring winpthreads" "" \
  182. "$SRC_PATH/mingw-w64/mingw-w64-libraries/winpthreads/configure" \
  183. --build="$BUILD" --host="$host" --disable-shared \
  184. --enable-static --prefix="$prefix/$host"
  185. execute "($arch): building winpthreads" "" \
  186. make -j $JOB_COUNT
  187. execute "($arch): installing winpthreads" "" \
  188. make install
  189. fi
  190. change_dir "$bld_path/gcc"
  191. execute "($arch): building GCC" "" \
  192. make -j $JOB_COUNT
  193. execute "($arch): installing GCC" "" \
  194. make install
  195. }
  196. while :; do
  197. case $1 in
  198. -h|--help)
  199. show_help
  200. exit 0
  201. ;;
  202. -j|--jobs)
  203. if [ "$2" ]; then
  204. JOB_COUNT=$2
  205. shift
  206. else
  207. arg_error "'--jobs' requires a non-empty option argument"
  208. fi
  209. ;;
  210. -p|--prefix)
  211. if [ "$2" ]; then
  212. PREFIX="$2"
  213. shift
  214. else
  215. arg_error "'--prefix' requires a non-empty option argument"
  216. fi
  217. ;;
  218. --prefix=?*)
  219. PREFIX=${1#*=}
  220. ;;
  221. --prefix=)
  222. arg_error "'--prefix' requires a non-empty option argument"
  223. ;;
  224. -r|--root)
  225. if [ "$2" ]; then
  226. ROOT_PATH_ARG="$2"
  227. shift
  228. else
  229. arg_error "'--root' requires a non-empty option argument"
  230. fi
  231. ;;
  232. --root=?*)
  233. ROOT_PATH_ARG="${1#*=}"
  234. ;;
  235. --root=)
  236. arg_error "'--root' requires a non-empty option argument"
  237. ;;
  238. --keep-artifacts)
  239. KEEP_ARTIFACTS=1
  240. ;;
  241. --disable-threads)
  242. ENABLE_THREADS=""
  243. ;;
  244. --cached-sources)
  245. CACHED_SOURCES=1
  246. ;;
  247. --binutils-branch)
  248. if [ "$2" ]; then
  249. BINUTILS_BRANCH="$2"
  250. shift
  251. else
  252. arg_error "'--binutils-branch' requires a non-empty option argument"
  253. fi
  254. ;;
  255. --binutils-branch=?*)
  256. BINUTILS_BRANCH=${1#*=}
  257. ;;
  258. --binutils-branch=)
  259. arg_error "'--binutils-branch' requires a non-empty option argument"
  260. ;;
  261. --gcc-branch)
  262. if [ "$2" ]; then
  263. GCC_BRANCH="$2"
  264. shift
  265. else
  266. arg_error "'--gcc-branch' requires a non-empty option argument"
  267. fi
  268. ;;
  269. --gcc-branch=?*)
  270. GCC_BRANCH=${1#*=}
  271. ;;
  272. --gcc-branch=)
  273. arg_error "'--gcc-branch' requires a non-empty option argument"
  274. ;;
  275. --linked-runtime)
  276. if [ "$2" ]; then
  277. LINKED_RUNTIME="$2"
  278. shift
  279. else
  280. arg_error "'--linked-runtime' requires a non-empty option argument"
  281. fi
  282. ;;
  283. --linked-runtime=?*)
  284. LINKED_RUNTIME=${1#*=}
  285. ;;
  286. --linked-runtime=)
  287. arg_error "'--linked-runtime' requires a non-empty option argument"
  288. ;;
  289. --mingw-w64-branch)
  290. if [ "$2" ]; then
  291. MINGW_W64_BRANCH="$2"
  292. shift
  293. else
  294. arg_error "'--mingw-w64-branch' requires a non-empty option argument"
  295. fi
  296. ;;
  297. --mingw-w64-branch=?*)
  298. MINGW_W64_BRANCH=${1#*=}
  299. ;;
  300. --mingw-w64-branch=)
  301. arg_error "'--mingw-w64-branch' requires a non-empty option argument"
  302. ;;
  303. i586)
  304. BUILD_I586=1
  305. ;;
  306. i686)
  307. BUILD_I686=1
  308. ;;
  309. x86_64)
  310. BUILD_X86_64=1
  311. ;;
  312. --)
  313. shift
  314. break
  315. ;;
  316. -?*)
  317. arg_error "unknown option '$1'"
  318. ;;
  319. ?*)
  320. arg_error "unknown arch '$1'"
  321. ;;
  322. *)
  323. break
  324. esac
  325. shift
  326. done
  327. NUM_BUILDS=$((BUILD_I586 + BUILD_I686 + BUILD_X86_64))
  328. if [ "$NUM_BUILDS" -eq 0 ]; then
  329. arg_error "no ARCH was specified"
  330. fi
  331. MISSING_EXECS=""
  332. for exec in g++ flex bison git makeinfo m4 bzip2 curl make diff; do
  333. if ! command -v "$exec" >/dev/null; then
  334. MISSING_EXECS="$MISSING_EXECS $exec"
  335. fi
  336. done
  337. if [ "$MISSING_EXECS" ]; then
  338. error_exit "missing required executable(s):$MISSING_EXECS"
  339. fi
  340. TOTAL_STEPS=0
  341. if [ ! "$CACHED_SOURCES" ]; then
  342. TOTAL_STEPS=$((TOTAL_STEPS + 4))
  343. fi
  344. if [ "$ENABLE_THREADS" ]; then
  345. THREADS_STEPS=3
  346. else
  347. THREADS_STEPS=0
  348. fi
  349. THREADS_STEPS=$((THREADS_STEPS * NUM_BUILDS))
  350. BUILD_STEPS=$((13 * NUM_BUILDS))
  351. TOTAL_STEPS=$((TOTAL_STEPS + THREADS_STEPS + BUILD_STEPS))
  352. if [ "$ROOT_PATH_ARG" ]; then
  353. ROOT_PATH=$(mkdir -p "$ROOT_PATH_ARG" && cd "$ROOT_PATH_ARG" && pwd)
  354. fi
  355. SRC_PATH="$ROOT_PATH/src"
  356. BLD_PATH="$ROOT_PATH/bld"
  357. LOG_FILE="$ROOT_PATH/build.log"
  358. if [ "$PREFIX" ]; then
  359. I586_PREFIX="$PREFIX"
  360. I686_PREFIX="$PREFIX"
  361. X86_64_PREFIX="$PREFIX"
  362. else
  363. I586_PREFIX="$ROOT_PATH/i586"
  364. I686_PREFIX="$ROOT_PATH/i686"
  365. X86_64_PREFIX="$ROOT_PATH/x86_64"
  366. fi
  367. CURRENT_STEP=1
  368. # clean log file for execute()
  369. mkdir -p "$ROOT_PATH"
  370. rm -f "$LOG_FILE"
  371. touch "$LOG_FILE"
  372. if [ ! "$CACHED_SOURCES" ]; then
  373. download_sources
  374. else
  375. if [ ! -f "$SRC_PATH/config.guess" ]; then
  376. arg_error "no sources found, run with --keep-artifacts first"
  377. fi
  378. fi
  379. BUILD=$(sh "$SRC_PATH/config.guess")
  380. change_dir "$SRC_PATH/gcc"
  381. execute "" "failed to download GCC dependencies" \
  382. ./contrib/download_prerequisites
  383. for i in mpc isl mpfr gmp; do
  384. ln -s "$SRC_PATH/gcc/$i" "$SRC_PATH/binutils/$i"
  385. done
  386. export CFLAGS="-O2"
  387. export CXXFLAGS="-O2"
  388. export LDFLAGS="-Wl,-O1,--sort-common,--as-needed"
  389. ADD_TO_PATH=()
  390. if [ "$BUILD_I586" ]; then
  391. build i586 "$I586_PREFIX"
  392. ADD_TO_PATH+=("'$I586_PREFIX/bin'")
  393. fi
  394. if [ "$BUILD_I686" ]; then
  395. build i686 "$I686_PREFIX"
  396. ADD_TO_PATH+=("'$I686_PREFIX/bin'")
  397. fi
  398. if [ "$BUILD_X86_64" ]; then
  399. build x86_64 "$X86_64_PREFIX"
  400. ADD_TO_PATH+=("'$X86_64_PREFIX/bin'")
  401. fi
  402. if [ ! "$KEEP_ARTIFACTS" ]; then
  403. remove_path "$SRC_PATH"
  404. remove_path "$BLD_PATH"
  405. remove_path "$LOG_FILE"
  406. fi
  407. echo "complete, to use MinGW-w64 everywhere add these to your \$PATH:"
  408. for add_to_path in "${ADD_TO_PATH[@]}"; do
  409. printf "\t%s\n" "$add_to_path"
  410. done
  411. exit 0