crosscompile.sh 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. #!/bin/sh
  2. #
  3. ################################################################################
  4. #
  5. # MODULE: crosscompile.sh
  6. # AUTHOR(S): Huidae Cho <grass4u gmail.com>
  7. # PURPOSE: Builds a cross-compiled portable package of GRASS GIS
  8. # COPYRIGHT: (C) 2019-2021 by Huidae Cho and the GRASS Development Team
  9. #
  10. # This program is free software under the GNU General Public
  11. # License (>=v2). Read the file COPYING that comes with GRASS
  12. # for details.
  13. #
  14. ################################################################################
  15. #
  16. # This script requires MXE <https://mxe.cc/> for cross-compilation and was
  17. # tested on Slackware 14.2 x86_64 with up-to-date packages from slackpkg and
  18. # sbopkg. It was also tested on WSLackware
  19. # <https://github.com/Mohsens22/WSLackware> in WSL
  20. # <https://docs.microsoft.com/en-us/windows/wsl/>.
  21. #
  22. # Basic steps:
  23. #
  24. # mkdir -p ~/usr/src
  25. # cd ~/usr/src
  26. # git clone https://github.com/mxe/mxe.git
  27. # cd mxe
  28. # echo MXE_TARGETS=x86_64-w64-mingw32.shared > settings.mk
  29. # make cc blas bzip2 cairo fftw freetype gdal geos lapack netcdf libpng \
  30. # pthreads readline libgnurx sqlite tiff zstd proj
  31. #
  32. # cd ~/usr/src
  33. # git clone https://github.com/OSGeo/grass.git
  34. # git clone https://github.com/OSGeo/grass-addons.git
  35. # cd grass
  36. # mswindows/crosscompile.sh --mxe-path=$HOME/usr/src/mxe --update --package \
  37. # > crosscompile.log 2>&1
  38. #
  39. # stop on errors
  40. set -e
  41. # default paths, but can be overriden from the command line
  42. mxe_path=${MXE_PATH-$HOME/usr/local/src/mxe}
  43. addons_path=${ADDONS_PATH-../grass-addons}
  44. freetype_include=${FREETYPE_INCLUDE-/usr/include/freetype2}
  45. # process options
  46. update=0
  47. package=0
  48. for opt; do
  49. case "$opt" in
  50. -h|--help)
  51. cat<<'EOT'
  52. Usage: crosscompile.sh [OPTIONS]
  53. -h, --help display this help message
  54. --mxe-path=PATH MXE path (default: $HOME/usr/local/src/mxe)
  55. --addons-path=PATH grass-addons path (default: ../grass-addons)
  56. --freetype-include=PATH FreeType include path
  57. (default: /usr/include/freetype2)
  58. --update update the current branch
  59. --package package the cross-compiled build as
  60. grass81-x86_64-w64-mingw32-YYYYMMDD.zip
  61. EOT
  62. exit
  63. ;;
  64. --mxe-path=*)
  65. mxe_path=`echo $opt | sed 's/^[^=]*=//'`
  66. ;;
  67. --addons-path=*)
  68. addons_path=`echo $opt | sed 's/^[^=]*=//'`
  69. ;;
  70. --freetype-include=*)
  71. freetype_include=`echo $opt | sed 's/^[^=]*=//'`
  72. ;;
  73. --update)
  74. update=1
  75. ;;
  76. --package)
  77. package=1
  78. ;;
  79. *)
  80. echo "$opt: unknown option"
  81. exit 1
  82. ;;
  83. esac
  84. done
  85. # see if we're inside the root of the GRASS source code
  86. if [ ! -f grass.pc.in ]; then
  87. echo "Please run this script from the root of the GRASS source code"
  88. exit 1
  89. fi
  90. # check paths
  91. errors=0
  92. if [ ! -d $mxe_path ]; then
  93. echo "$mxe_path: not found"
  94. errors=1
  95. fi
  96. if [ ! -d $freetype_include ]; then
  97. echo "$freetype_include: not found"
  98. errors=1
  99. fi
  100. if [ $update -eq 1 -a ! -d .git ]; then
  101. echo "not a git repository"
  102. errors=1
  103. fi
  104. if [ $errors -eq 1 ]; then
  105. exit 1
  106. fi
  107. ################################################################################
  108. # Start
  109. echo "Started cross-compilation: `date`"
  110. echo
  111. # update the current branch if requested
  112. if [ $update -eq 1 -a -d .git ]; then
  113. git pull
  114. fi
  115. ################################################################################
  116. # Compile the native architecture for generating document files
  117. CFLAGS="-g -O2 -Wall" \
  118. CXXFLAGS="-g -O2 -Wall" \
  119. LDFLAGS="-lcurses" \
  120. ./configure \
  121. --with-nls \
  122. --with-readline \
  123. --with-wxwidgets \
  124. --with-freetype-includes=$freetype_include \
  125. --with-bzlib \
  126. --with-postgres \
  127. --with-pthread \
  128. --with-openmp \
  129. --with-blas \
  130. --with-lapack \
  131. --with-geos \
  132. --with-netcdf \
  133. >> /dev/stdout
  134. make clean default
  135. if [ -d $addons_path ]; then
  136. MODULE_TOPDIR=`pwd`
  137. (
  138. cd $addons_path
  139. if [ $update -eq 1 -a -d .git ]; then
  140. git pull
  141. fi
  142. cd src
  143. make MODULE_TOPDIR=$MODULE_TOPDIR clean default
  144. )
  145. fi
  146. build_arch=`sed -n '/^ARCH[ \t]*=/{s/^.*=[ \t]*//; p}' include/Make/Platform.make`
  147. for i in \
  148. config.log \
  149. include/Make/Platform.make \
  150. include/Make/Doxyfile_arch_html \
  151. include/Make/Doxyfile_arch_latex \
  152. error.log \
  153. ; do
  154. cp -a $i $i.$build_arch
  155. done
  156. ################################################################################
  157. # Cross-compile the target architecture
  158. arch=x86_64-w64-mingw32
  159. shared=$arch.shared
  160. mxe_bin=$mxe_path/usr/bin/$shared
  161. mxe_shared=$mxe_path/usr/$shared
  162. CC=$mxe_bin-gcc \
  163. CXX=$mxe_bin-g++ \
  164. CFLAGS="-g -O2 -Wall" \
  165. CXXFLAGS="-g -O2 -Wall" \
  166. AR=$mxe_bin-ar \
  167. RANLIB=$mxe_bin-ranlib \
  168. WINDRES=$mxe_bin-windres \
  169. PKG_CONFIG=$mxe_bin-pkg-config \
  170. ./configure \
  171. --build=$build_arch \
  172. --host=$arch \
  173. --with-nls \
  174. --with-readline \
  175. --with-wxwidgets \
  176. --with-freetype-includes=$mxe_shared/include/freetype2 \
  177. --with-bzlib \
  178. --with-postgres \
  179. --with-pthread \
  180. --with-openmp \
  181. --with-blas \
  182. --with-lapack \
  183. --with-geos=$mxe_shared/bin/geos-config \
  184. --with-netcdf=$mxe_shared/bin/nc-config \
  185. --with-gdal=$mxe_shared/bin/gdal-config \
  186. --with-opengl=windows \
  187. >> /dev/stdout
  188. make clean default
  189. if [ -d $addons_path ]; then
  190. (
  191. cd $addons_path
  192. if [ $update -eq 1 -a -d .git ]; then
  193. git pull
  194. fi
  195. cd src
  196. make MODULE_TOPDIR=$MODULE_TOPDIR clean default
  197. )
  198. fi
  199. arch=`sed -n '/^ARCH[ \t]*=/{s/^.*=[ \t]*//; p}' include/Make/Platform.make`
  200. for i in \
  201. config.log \
  202. include/Make/Platform.make \
  203. include/Make/Doxyfile_arch_html \
  204. include/Make/Doxyfile_arch_latex \
  205. error.log \
  206. ; do
  207. cp -a $i $i.$arch
  208. done
  209. ################################################################################
  210. # Copy document files from the native build
  211. build_dist=dist.$build_arch
  212. dist=dist.$arch
  213. for i in \
  214. docs \
  215. gui/wxpython/xml \
  216. ; do
  217. rm -rf $dist/$i
  218. cp -a $build_dist/$i $dist/$i
  219. done
  220. ################################################################################
  221. # Copy MXE files
  222. for i in \
  223. libblas.dll \
  224. libbz2.dll \
  225. libcairo-2.dll \
  226. libcrypto-3-x64.dll \
  227. libcurl-4.dll \
  228. libdf-0.dll \
  229. libexpat-1.dll \
  230. libfftw3-3.dll \
  231. libfontconfig-1.dll \
  232. libfreetype-6.dll \
  233. libfreexl-1.dll \
  234. libgcc_s_seh-1.dll \
  235. libgcrypt-20.dll \
  236. libgdal-20.dll \
  237. libgeos-3-6-2.dll \
  238. libgeos_c-1.dll \
  239. libgeotiff-2.dll \
  240. libgfortran-3.dll \
  241. libgif-7.dll \
  242. libglib-2.0-0.dll \
  243. libgnurx-0.dll \
  244. libgomp-1.dll \
  245. libgpg-error-0.dll \
  246. libgta-0.dll \
  247. libharfbuzz-0.dll \
  248. libhdf5-8.dll \
  249. libhdf5_hl-8.dll \
  250. libiconv-2.dll \
  251. libidn2-0.dll \
  252. libintl-8.dll \
  253. libjpeg-9.dll \
  254. libjson-c-4.dll \
  255. liblapack.dll \
  256. liblzma-5.dll \
  257. libmfhdf-0.dll \
  258. libmysqlclient.dll \
  259. libnetcdf.dll \
  260. libopenjp2.dll \
  261. libpcre-1.dll \
  262. libpixman-1-0.dll \
  263. libpng16-16.dll \
  264. libportablexdr-0.dll \
  265. libpq.dll \
  266. libproj-13.dll \
  267. libquadmath-0.dll \
  268. libreadline8.dll \
  269. libspatialite-7.dll \
  270. libsqlite3-0.dll \
  271. libssh2-1.dll \
  272. libssl-3-x64.dll \
  273. libstdc++-6.dll \
  274. libtermcap.dll \
  275. libtiff-5.dll \
  276. libunistring-2.dll \
  277. libwebp-7.dll \
  278. libwinpthread-1.dll \
  279. libxml2-2.dll \
  280. libzstd.dll \
  281. zlib1.dll \
  282. ; do
  283. cp -a $mxe_shared/bin/$i $dist/lib
  284. done
  285. for i in \
  286. proj \
  287. gdal \
  288. ; do
  289. rm -rf $dist/share/$i
  290. cp -a $mxe_shared/share/$i $dist/share/$i
  291. done
  292. ################################################################################
  293. # Post-compile process
  294. version=`sed -n '/^INST_DIR[ \t]*=/{s/^.*grass//; p}' include/Make/Platform.make`
  295. rm -f $dist/grass.tmp
  296. cp -a bin.$arch/grass.py $dist/etc/grass$version.py
  297. cat<<'EOT' | sed "s/\$version/$version/g" > $dist/grass.bat
  298. @echo off
  299. setlocal EnableDelayedExpansion
  300. set GISBASE=%~dp0
  301. set GISBASE=%GISBASE:~0,-1%
  302. set GRASS_PROJSHARE=%GISBASE%\share\proj
  303. set PROJ_LIB=%GISBASE%\share\proj
  304. set GDAL_DATA=%GISBASE%\share\gdal
  305. rem XXX: Do we need these variables?
  306. rem set GEOTIFF_CSV=%GISBASE%\share\epsg_csv
  307. rem set FONTCONFIG_FILE=%GISBASE%\etc\fonts.conf
  308. if defined GRASS_PYTHON (
  309. if not exist "%GRASS_PYTHON%" (
  310. echo.
  311. echo %GRASS_PYTHON% not found
  312. echo Please fix GRASS_PYTHON
  313. echo.
  314. pause
  315. goto :eof
  316. )
  317. ) else (
  318. rem Change this variable to override auto-detection of python.exe in
  319. rem PATH
  320. set GRASS_PYTHON=C:\Python39\python.exe
  321. rem For portable installation, use %~d0 for the changing drive letter
  322. rem set GRASS_PYTHON=%~d0\Python39\python.exe
  323. if not exist "%GRASS_PYTHON%" (
  324. set GRASS_PYTHON=
  325. for /f usebackq %%i in (`where python.exe`) do if "!GRASS_PYTHON!" == "" set GRASS_PYTHON=%%i
  326. )
  327. if not defined GRASS_PYTHON (
  328. echo.
  329. echo python.exe not found in PATH
  330. echo Please set GRASS_PYTHON
  331. echo.
  332. pause
  333. goto :eof
  334. )
  335. )
  336. rem XXX: Do we need PYTHONHOME?
  337. rem for %%i in (%GRASS_PYTHON%) do set PYTHONHOME=%%~dpi
  338. rem If GRASS_SH is externally defined, that shell will be used; Otherwise,
  339. rem GISBASE\etc\sh.bat will be used if it exists; If not, cmd.exe will be used;
  340. rem This check is mainly for supporting BusyBox for Windows (busybox64.exe)
  341. rem (https://frippery.org/busybox/)
  342. if not defined GRASS_SH (
  343. set GRASS_SH=%GISBASE%\etc\sh.bat
  344. if not exist "!GRASS_SH!" set GRASS_SH=
  345. )
  346. rem With busybox64.exe and Firefox as the default browser, g.manual fails with
  347. rem "Your Firefox profile cannot be loaded. It may be missing or inaccessible";
  348. rem I tried to set GRASS_HTML_BROWSER to the full path of chrome.exe, but it
  349. rem didn't work; Setting BROWSER to its full path according to the webbrowser
  350. rem manual worked
  351. if "%GRASS_SH%" == "%GISBASE%\etc\sh.bat" if not defined BROWSER (
  352. for %%i in ("%ProgramFiles%" "%ProgramFiles(x86)%") do (
  353. if not defined BROWSER (
  354. set BROWSER=%%i
  355. set BROWSER=!BROWSER:"=!
  356. if exist "!BROWSER!\Google\Chrome\Application\chrome.exe" (
  357. set BROWSER=!BROWSER!\Google\Chrome\Application\chrome.exe
  358. ) else (
  359. set BROWSER=
  360. )
  361. )
  362. )
  363. )
  364. if not exist "%GISBASE%\etc\fontcap" (
  365. pushd .
  366. %~d0
  367. cd %GISBASE%\lib
  368. set GISRC=dummy
  369. "%GISBASE%\bin\g.mkfontcap.exe"
  370. popd
  371. )
  372. "%GRASS_PYTHON%" "%GISBASE%\etc\grass$version.py" %*
  373. if %ERRORLEVEL% geq 1 pause
  374. EOT
  375. unix2dos $dist/grass.bat
  376. # package if requested
  377. if [ $package -eq 1 ]; then
  378. date=`date +%Y%m%d`
  379. rm -f grass
  380. ln -s $dist grass
  381. rm -f grass*-$arch-*.zip
  382. zip -r grass$version-$arch-$date.zip grass
  383. rm -f grass
  384. fi
  385. echo
  386. echo "Completed cross-compilation: `date`"