Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

545 lines
13 KiB

5 years ago
  1. #!/bin/sh
  2. ##
  3. ## Installs package dependencies and builds the application.
  4. ##
  5. # Don't exit if some command fails.
  6. set +e
  7. # Disable file globbing.
  8. set -f
  9. # Boolean variables are true if non-empty and false otherwise.
  10. # Command to install packages.
  11. PKGCMD=
  12. # Args to pass to $PKGCMD.
  13. PKGARGS=
  14. # Required packages.
  15. PACKAGES=
  16. # Whether package installation requires root permissions.
  17. PKG_INSTALL_AS_ROOT=true
  18. # Whether to skip package installation altogether.
  19. PKG_INSTALL_SKIP=
  20. # Whether to force package installation, even if it does not seem
  21. # necessary.
  22. PKG_INSTALL_FORCE=
  23. # Only test if the OS is handled by this script.
  24. DRY_RUN=
  25. # If and where to install the program.
  26. INSTALL_DIR=
  27. # Whether we can install packages.
  28. OS_IS_HANDLED=true
  29. # Which OSs installer to use
  30. OS=
  31. ## +-----------------------------------------------------------+
  32. ## * Utility Functions
  33. ## +-----------------------------------------------------------+
  34. usage()
  35. {
  36. cat <<EOF
  37. usage:$(basename "$0") [--help|-n|-i DIR|[-d -D]|[--os OS]]
  38. -n Don't do anything, but check if this OS is handled.
  39. -i DIR Install the program in the given directory.
  40. -d Force dependency installattion.
  41. -D Skip dependency installattion.
  42. --os OS Use the given OS's installer
  43. --help Display this message.
  44. EOF
  45. exit "$1"
  46. }
  47. # Search for command $1 in PATH. Print its absolute filename.
  48. which()
  49. {
  50. if [ -z "$1" ]; then
  51. return 1
  52. fi
  53. IFS=:
  54. for dir in $PATH; do
  55. if [ -x "$dir/$1" ]; then
  56. printf "%s" "$dir/$1"
  57. unset IFS
  58. return 0
  59. fi
  60. done
  61. unset IFS
  62. return 1
  63. }
  64. # Quote $@ for the shell.
  65. quote()
  66. {
  67. quoted=
  68. for arg; do
  69. qarg=$(printf "%s" "$arg" | sed -e 's/[|&;<>()$\`"'\'' ]/\\&/g')
  70. if [ -z "$quoted" ]; then
  71. quoted=$qarg
  72. else
  73. quoted="$quoted $qarg"
  74. fi
  75. done
  76. printf "%s" "$quoted"
  77. }
  78. # Attempt to exec $@ as root.
  79. exec_privileged() {
  80. if [ -z "$1" ]; then
  81. echo "internal error: command is empty"
  82. exit 2
  83. fi
  84. if [ -w / ]; then
  85. "$@"
  86. elif which sudo >/dev/null 2>&1; then
  87. sudo -- "$@"
  88. retval=$?
  89. sudo -k
  90. return $retval
  91. elif which su >/dev/null 2>&1; then
  92. su -c "$(quote "$@")"
  93. else
  94. echo "No such program: sudo or su"
  95. exit 1
  96. fi
  97. }
  98. # Test if $1 is in PATH or exit with a failure status.
  99. assert_program()
  100. {
  101. if ! which "$1" >/dev/null 2>&1; then
  102. echo "No such program: $1"
  103. exit 1
  104. fi
  105. }
  106. # Source filename $1 and echo variable $2.
  107. source_var()
  108. {
  109. if ! [ -f "$1" ] || ! [ -r "$1" ] || [ -z "$2" ]; then
  110. return 1
  111. fi
  112. # shellcheck source=/dev/null
  113. . "$1"
  114. eval "printf '%s\n' \$$2"
  115. return 0
  116. }
  117. exit_success()
  118. {
  119. echo "==========================="
  120. echo " Build succeeded. :O) "
  121. echo "==========================="
  122. exit 0
  123. }
  124. exit_fail()
  125. {
  126. echo "==========================="
  127. echo " Build failed. ;o( "
  128. echo "==========================="
  129. if [ -z "$PKG_INSTALL_FORCE" ]; then
  130. echo "Note: maybe try the '-d' option."
  131. fi
  132. exit 1
  133. }
  134. # Return 0, if all required packages seem to be installed.
  135. have_packages_installed()
  136. {
  137. {
  138. which pkg-config || return 1
  139. if ! [ -f configure ];then
  140. which autoreconf || return 1
  141. which automake || return 1
  142. fi
  143. for lib in libpng glib-2.0 poppler poppler-glib zlib; do
  144. pkg-config --exists $lib || return 1
  145. done
  146. which make || return 1
  147. which gcc || which cc || return 1
  148. which g++ || which c++ || return 1
  149. cc $(pkg-config --cflags poppler) -o /dev/null -E - 2>/dev/null <<EOF
  150. #include <PDFDocEncoding.h>
  151. EOF
  152. [ $? -eq 0 ] || return 1
  153. return 0
  154. } >/dev/null 2>&1
  155. }
  156. handle_options()
  157. {
  158. while [ $# -gt 0 ]; do
  159. case $1 in
  160. --help) usage 0;;
  161. -n) DRY_RUN=true;;
  162. -d) PKG_INSTALL_FORCE=true ;;
  163. -D) PKG_INSTALL_SKIP=true ;;
  164. -i)
  165. shift
  166. [ $# -gt 0 ] || usage 1
  167. if [ "${1%%/}" != "${PWD%%/}" ]; then
  168. INSTALL_DIR=$1
  169. fi ;;
  170. --os)
  171. shift
  172. [ $# -gt 0 ] || usage 1
  173. OS="$1"
  174. ;;
  175. *) usage 1 ;;
  176. esac
  177. shift
  178. done
  179. if [ -n "$PKG_INSTALL_SKIP" ] && [ -n "$PKG_INSTALL_FORCE" ]; then
  180. usage 1
  181. fi
  182. }
  183. ## +-----------------------------------------------------------+
  184. ## * OS Functions
  185. ## +-----------------------------------------------------------+
  186. # Archlinux
  187. os_arch() {
  188. if ! [ -e "/etc/arch-release" ]; then
  189. return 1;
  190. fi
  191. PKGCMD=pacman
  192. PKGARGS="-S --needed"
  193. PACKAGES="base-devel libpng zlib poppler-glib"
  194. return 0;
  195. }
  196. # CentOS
  197. os_centos() {
  198. if ! [ -e "/etc/centos-release" ]; then
  199. return 1
  200. fi
  201. PKGCMD=yum
  202. if yum help install-n >/dev/null 2>&1; then
  203. PKGARGS=install-n
  204. else
  205. PKGARGS=install
  206. fi
  207. PACKAGES="autoconf
  208. automake
  209. gcc
  210. gcc-c++
  211. libpng-devel
  212. make
  213. pkgconfig
  214. poppler-devel
  215. poppler-glib-devel
  216. zlib-devel"
  217. return 0
  218. }
  219. # FreeBSD
  220. os_freebsd() {
  221. if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "FreeBSD" ]; then
  222. return 1
  223. fi
  224. PKGCMD=pkg
  225. PKGARGS=install
  226. PACKAGES="autotools poppler-glib png pkgconf"
  227. return 0
  228. }
  229. # OpenBSD
  230. os_openbsd() {
  231. if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "OpenBSD" ]; then
  232. return 1
  233. fi
  234. PKGCMD=pkg_add
  235. PKGARGS="-uU"
  236. PACKAGES="autoconf-2.69p2 automake-1.15.1 poppler poppler-utils png"
  237. export AUTOCONF_VERSION=2.69
  238. export AUTOMAKE_VERSION=1.15
  239. if whereis clang++ ;then
  240. export CXX=clang++
  241. elif whereis eg++ ;then
  242. export CXX=eg++
  243. else
  244. export CXX=eg++
  245. PACKAGES="${PACKAGES} g++"
  246. fi
  247. export CXXFLAGS="-std=c++11 -I/usr/local/include/poppler -I/usr/local/include"
  248. return 0
  249. }
  250. # Fedora
  251. os_fedora() {
  252. if ! [ -e "/etc/fedora-release" ]; then
  253. return 1
  254. fi
  255. PKGCMD=dnf
  256. PKGARGS=install
  257. PACKAGES="autoconf
  258. automake
  259. gcc
  260. gcc-c++
  261. libpng-devel
  262. make
  263. poppler-devel
  264. poppler-glib-devel
  265. zlib-devel"
  266. VERSION=$(source_var /etc/os-release VERSION_ID)
  267. if [ -n "$VERSION" ] && [ "$VERSION" -ge 26 ]; then
  268. PACKAGES="$PACKAGES pkgconf"
  269. else
  270. PACKAGES="$PACKAGES pkgconfig"
  271. fi
  272. return 0
  273. }
  274. # Debian/Ubuntu
  275. os_debian() {
  276. if ! [ -e "/etc/debian_version" ]; then
  277. return 1
  278. fi
  279. PACKAGES="autoconf
  280. automake
  281. g++
  282. gcc
  283. libpng-dev
  284. libpoppler-dev
  285. libpoppler-glib-dev
  286. libpoppler-private-dev
  287. libz-dev
  288. make
  289. pkg-config"
  290. PKGCMD=apt-get
  291. PKGARGS=install
  292. return 0
  293. }
  294. # Msys2
  295. os_msys2() {
  296. if [ -z "$MSYSTEM" ] || ! [ -r "/etc/profile" ]; then
  297. return 1
  298. fi
  299. case $MSYSTEM in
  300. MINGW64)
  301. PACKAGES="base-devel
  302. mingw-w64-x86_64-libpng
  303. mingw-w64-x86_64-poppler
  304. mingw-w64-x86_64-toolchain
  305. mingw-w64-x86_64-zlib" ;;
  306. MINGW32)
  307. PACKAGES="base-devel
  308. mingw-w64-i686-libpng
  309. mingw-w64-i686-poppler
  310. mingw-w64-i686-toolchain
  311. mingw-w64-i686-zlib" ;;
  312. MSYS)
  313. case $(uname -m) in
  314. x86_64)
  315. MSYSTEM=MINGW64 ;;
  316. *)
  317. MSYSTEM=MINGW32 ;;
  318. esac
  319. export MSYSTEM
  320. # shellcheck source=/dev/null
  321. . /etc/profile
  322. eval "exec $(quote "$0" "$@")" ;;
  323. *)
  324. echo "Unrecognized MSYSTEM value: $MSYSTEM"
  325. exit 1 ;;
  326. esac
  327. PKGCMD=pacman
  328. PKGARGS="-S --needed"
  329. PKG_INSTALL_AS_ROOT=
  330. return 0
  331. }
  332. # MacOS
  333. os_macos() {
  334. if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "Darwin" ]; then
  335. return 1
  336. elif which brew >/dev/null 2>&1; then
  337. PKGCMD=brew
  338. PKGARGS=install
  339. PACKAGES="pkg-config poppler automake"
  340. PKG_INSTALL_AS_ROOT=
  341. # homebrew install libffi as keg-only, meaning we need to set
  342. # PKG_CONFIG_PATH manually so configure can find it
  343. export PKG_CONFIG_PATH="$(brew --prefix libffi)/lib/pkgconfig/"
  344. elif which port >/dev/null 2>&1; then
  345. PKGCMD=port
  346. PKGARGS=install
  347. PACKAGES="pkgconfig poppler automake libpng"
  348. else
  349. return 1
  350. fi
  351. return 0
  352. }
  353. # NixOS
  354. os_nixos() {
  355. # Already in the nix-shell.
  356. if [ -n "$AUTOBUILD_NIX_SHELL" ]; then
  357. return 0
  358. fi
  359. if ! which nix-shell >/dev/null 2>&1; then
  360. return 1
  361. fi
  362. if [ -n "$DRY_RUN" ]; then
  363. return 0
  364. fi
  365. command="AUTOBUILD_NIX_SHELL=true"
  366. command="$command;export AUTOBUILD_NIX_SHELL"
  367. command="$command;$(quote "$0" "$@")"
  368. exec nix-shell --pure --command "$command" \
  369. -p gcc gnumake automake autoconf pkgconfig libpng zlib poppler
  370. }
  371. # Gentoo
  372. os_gentoo() {
  373. if ! [ -e "/etc/gentoo-release" ]; then
  374. return 1
  375. fi
  376. PKGCMD=emerge
  377. PKGARGS=--noreplace
  378. PACKAGES="app-text/poppler
  379. dev-util/pkgconfig
  380. media-libs/libpng
  381. sys-devel/autoconf
  382. sys-devel/automake
  383. sys-devel/gcc
  384. sys-devel/make
  385. sys-libs/zlib"
  386. return 0
  387. }
  388. # By Parameter --os
  389. os_argument() {
  390. [ -z "$OS" ] && return 1
  391. case $OS in
  392. macos) os_macos "$@";;
  393. freebsd) os_freebsd "$@";;
  394. arch) os_arch "$@";;
  395. centos) os_centos "$@";;
  396. openbsd) os_openbsd "$@";;
  397. fedora) os_fedora "$@";;
  398. debian) os_debian "$@";;
  399. gentoo) os_gentoo "$@";;
  400. msys2) os_msys2 "$@";;
  401. nixos) os_nixos "$@";;
  402. *) echo "Invalid --os argument: $OS"
  403. exit 1
  404. esac || {
  405. echo "Unable to install on this system as $OS"
  406. exit 1
  407. }
  408. }
  409. ## +-----------------------------------------------------------+
  410. ## * Figure out were we are, install deps and build the program
  411. ## +-----------------------------------------------------------+
  412. handle_options "$@"
  413. os_argument "$@" || \
  414. os_macos "$@" || \
  415. os_freebsd "$@" || \
  416. os_arch "$@" || \
  417. os_centos "$@" || \
  418. os_openbsd "$@" || \
  419. os_fedora "$@" || \
  420. os_debian "$@" || \
  421. os_gentoo "$@" || \
  422. os_msys2 "$@" || \
  423. os_nixos "$@" || \
  424. {
  425. OS_IS_HANDLED=
  426. if [ -z "$DRY_RUN" ]; then
  427. echo "Failed to recognize this system, trying to continue."
  428. fi
  429. }
  430. if [ -n "$DRY_RUN" ]; then
  431. [ -n "$OS_IS_HANDLED" ]
  432. exit $?
  433. fi
  434. if [ -n "$PKGCMD" ];then
  435. echo "---------------------------"
  436. echo " Installing packages "
  437. echo "---------------------------"
  438. if [ -n "$PKG_INSTALL_SKIP" ]; then
  439. echo "Skipping package installation (as requested)"
  440. elif [ -z "$PKG_INSTALL_FORCE" ] && have_packages_installed; then
  441. echo "Skipping package installation (already installed)"
  442. else
  443. assert_program "$PKGCMD"
  444. echo "$PKGCMD $PKGARGS $PACKAGES"
  445. if [ -n "$PKG_INSTALL_AS_ROOT" ]; then
  446. exec_privileged $PKGCMD $PKGARGS $PACKAGES
  447. else
  448. $PKGCMD $PKGARGS $PACKAGES
  449. fi
  450. fi
  451. echo
  452. fi
  453. echo "---------------------------"
  454. echo " Configuring and compiling "
  455. echo "---------------------------"
  456. # Try to be in the correct directory.
  457. if which dirname >/dev/null 2>&1; then
  458. cd "$(dirname "$0")" || {
  459. echo "Failed to change into the source directory"
  460. exit 1
  461. }
  462. fi
  463. # Create the configure script.
  464. if ! [ -f ./configure ]; then
  465. assert_program autoreconf
  466. echo "autoreconf -i"
  467. autoreconf -i
  468. [ -f ./configure ] || exit_fail
  469. fi
  470. # Build the program.
  471. if [ -n "$INSTALL_DIR" ]; then
  472. prefix=--bindir=$INSTALL_DIR
  473. fi
  474. echo "./configure -q $prefix && make -s"
  475. eval "./configure -q $(quote "$prefix") && make -s || exit_fail"
  476. echo
  477. if [ -n "$INSTALL_DIR" ]; then
  478. echo "---------------------------"
  479. echo " Installing "
  480. echo "---------------------------"
  481. echo make -s install
  482. if mkdir -p -- "$INSTALL_DIR" && [ -w "$INSTALL_DIR" ]; then
  483. make install || exit_fail
  484. else
  485. exec_privileged make install || exit_fail
  486. fi
  487. # Copy dynamic libraries on windows.
  488. if [ -f epdfinfo.exe ]; then
  489. assert_program awk
  490. assert_program ldd
  491. for dll in $(ldd epdfinfo.exe | awk '/\/mingw/ {print $3}'); do
  492. cp -u "$dll" "$INSTALL_DIR"
  493. done
  494. fi
  495. echo
  496. fi
  497. exit_success
  498. # Local Variables:
  499. # compile-command: "shellcheck autobuild"
  500. # End: