makerelease-osx.mk 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. # Any copyright is dedicated to the Public Domain.
  2. # http://creativecommons.org/publicdomain/zero/1.0/
  3. # Written by Nils Maier
  4. # This make file will:
  5. # - Download a set of dependencies and verify the known-good hashes.
  6. # - Build static libraries of aria2 dependencies.
  7. # - Create a statically linked, aria2 release.
  8. # - The build will have all major features enabled, and will use
  9. # AppleTLS and GMP.
  10. # - Create a corresponding .tar.bz containing the binaries:
  11. # - Create a corresponding .pkg installer.
  12. # - Create a corresponding .dmg image containing said installer.
  13. #
  14. # This Makefile will also run all `make check` targets.
  15. #
  16. # The dependencies currently build are:
  17. # - zlib (compression, in particular web compression)
  18. # - c-ares (asynchronous DNS resolver)
  19. # - expat (XML parser, for metalinks)
  20. # - gmp (multi-precision arithmetric library, for DHKeyExchange, BitTorrent)
  21. # - sqlite3 (self-contained SQL database, for Firefox3 cookie reading)
  22. # - cppunit (unit tests for C++, framework in use by aria2 `make check`)
  23. #
  24. #
  25. # To use this Makefile, do something along the lines of
  26. # - $ mkdir build-release
  27. # - $ cd build-release
  28. # - $ virtualenv .
  29. # - $ . bin/activate
  30. # - $ pip install sphinx-build
  31. # - $ ln -s ../makerelease-os.mk Makefile
  32. # - $ make
  33. #
  34. # To make an both builds use instead:
  35. # - $ make multi
  36. #
  37. # If you haven't checkout out a release tag, you need to specify NON_RELEASE.
  38. # $ export NON_RELEASE=1
  39. # to generate a dist with git commit
  40. # $ export NON_RELEASE=force
  41. # to force this script to behave like it was on a tag.
  42. #
  43. # Note: This Makefile expects to be called from a git clone of aria2.
  44. #
  45. # Note: In theory, everything can be build in parallel, however the sub-makes
  46. # will be called with an appropriate -j flag. Building the `deps` target in
  47. # parallel before a general make might be beneficial, as the dependencies
  48. # usually bottle-neck on the configure steps.
  49. #
  50. # Note: Of course, you need to have XCode with the command line tools
  51. # installed for this to work, aka. a working compiler...
  52. #
  53. # Note: We're locally building the dependencies here, static libraries only.
  54. # This is required, because when using brew or MacPorts, which also provide
  55. # dynamic libraries, the linker will pick up the dynamic versions, always,
  56. # with no way to instruct the linker otherwise.
  57. # If you're building aria2 just for yourself and your system, using brewed
  58. # libraries is fine as well.
  59. #
  60. # Note: This Makefile is riddled with mac-isms. It will not work on *nix.
  61. #
  62. # Note: The convoluted way to create separate arch builds and later merge them
  63. # with lipo is because of two things:
  64. # 1) Avoid patching c-ares, which hardcodes some sizes in its headers.
  65. #
  66. # Note: This Makefile uses resources from osx-package when creating the
  67. # *.pkg and *.dmg targets
  68. SHELL := bash
  69. # A bit awkward, but OSX doesn't have a proper `readlink -f`.
  70. SRCDIR := $(shell dirname $(lastword $(shell stat -f "%N %Y" $(lastword $(MAKEFILE_LIST)))))
  71. # Same as in script-helper, but a bit easier on the eye (but more error prone)
  72. # and Makefile compatible
  73. BASE_VERSION := $(shell grep AC_INIT $(SRCDIR)/configure.ac | cut -d'[' -f3 | cut -d']' -f1)
  74. ifeq ($(NON_RELEASE),)
  75. VERSION := $(BASE_VERSION)
  76. else
  77. ifeq ($(NON_RELEASE),force)
  78. VERSION := $(BASE_VERSION)
  79. else
  80. VERSION := $(subst release-,,$(shell git describe --tags))
  81. endif
  82. endif
  83. # Set up compiler.
  84. CC = cc
  85. export CC
  86. CXX = c++ -stdlib=libc++
  87. export CXX
  88. # Set up compiler/linker flags.
  89. OPTFLAGS ?= -Os
  90. CFLAGS ?= -mmacosx-version-min=10.10 $(OPTFLAGS)
  91. export CFLAGS
  92. CXXFLAGS ?= -mmacosx-version-min=10.10 $(OPTFLAGS)
  93. export CXXFLAGS
  94. LDFLAGS ?= -Wl,-dead_strip
  95. export LDFLAGS
  96. LTO_FLAGS = -flto -ffunction-sections -fdata-sections
  97. # Dependency versions
  98. zlib_version = 1.2.11
  99. zlib_hash = e6d119755acdf9104d7ba236b1242696940ed6dd
  100. zlib_url = http://zlib.net/zlib-$(zlib_version).tar.gz
  101. expat_version = 2.2.0
  102. expat_hash = 8453bc52324be4c796fd38742ec48470eef358b3
  103. expat_url = http://sourceforge.net/projects/expat/files/expat/$(expat_version)/expat-$(expat_version).tar.bz2
  104. expat_cflags=$(LTO_FLAGS)
  105. expat_ldflags=$(CFLAGS) $(LTO_FLAGS)
  106. cares_version = 1.13.0
  107. cares_hash = dde50284cc3d505fb2463ff6276e61d5531b1d68
  108. cares_url = https://c-ares.haxx.se/download/c-ares-$(cares_version).tar.gz
  109. cares_confflags = "--enable-optimize=$(OPTFLAGS)"
  110. cares_cflags=$(LTO_FLAGS)
  111. cares_ldflags=$(CFLAGS) $(LTO_FLAGS)
  112. sqlite_version = autoconf-3190300
  113. sqlite_hash = 58f2cabffb3ff4761a3ac7f834d9db7b46307c1f
  114. sqlite_url = https://sqlite.org/2017/sqlite-$(sqlite_version).tar.gz
  115. sqlite_cflags=$(LTO_FLAGS)
  116. sqlite_ldflags=$(CFLAGS) $(LTO_FLAGS)
  117. gmp_version = 6.1.2
  118. gmp_hash = 366ded6a44cd108ba6b3f5b9a252eab3f3a95cdf
  119. gmp_url = https://ftp.gnu.org/gnu/gmp/gmp-$(gmp_version).tar.bz2
  120. gmp_confflags = --disable-cxx --enable-assembly --with-pic --enable-fat
  121. libgpgerror_version = 1.21
  122. libgpgerror_hash = ef1dfb2f8761f019091180596e9e638d8cc37513
  123. libgpgerror_url = https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-$(libgpgerror_version).tar.bz2
  124. libgpgerror_cflags=$(LTO_FLAGS)
  125. libgpgerror_ldflags=$(CFLAGS) $(LTO_FLAGS)
  126. libgpgerror_confflags = --with-pic --disable-languages --disable-doc --disable-nls
  127. libgcrypt_version = 1.6.5
  128. libgcrypt_hash = c3a5a13e717f7b3e3895650afc1b6e0d3fe9c726
  129. libgcrypt_url = https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-$(libgcrypt_version).tar.bz2
  130. libgcrypt_confflags=--with-gpg-error-prefix=$(PWD)/arch --disable-O-flag-munging --disable-asm --disable-amd64-as-feature-detection
  131. libssh2_version = 1.8.0
  132. libssh2_hash = baf2d1fb338eee531ba9b6b121c64235e089e0f5
  133. libssh2_url = https://www.libssh2.org/download/libssh2-$(libssh2_version).tar.gz
  134. libssh2_cflags=$(LTO_FLAGS)
  135. libssh2_ldflags=$(CFLAGS) $(LTO_FLAGS)
  136. libssh2_confflags = --with-pic --without-openssl --with-libgcrypt=$(PWD)/arch --with-libgcrypt-prefix=$(PWD)/arch
  137. libssh2_nocheck = yes
  138. cppunit_version = 1.12.1
  139. cppunit_hash = f1ab8986af7a1ffa6760f4bacf5622924639bf4a
  140. cppunit_url = http://sourceforge.net/projects/cppunit/files/cppunit/$(cppunit_version)/cppunit-$(cppunit_version).tar.gz
  141. # ARCHLIBS that can be template build
  142. ARCHLIBS = expat cares sqlite gmp libgpgerror libgcrypt libssh2 cppunit
  143. # NONARCHLIBS that cannot be template build
  144. NONARCHLIBS = zlib
  145. # Tags
  146. THIS_TAG := $(shell git describe --abbrev=0 $$(git rev-list --tags --max-count=1))
  147. PREV_TAG := $(shell git describe --abbrev=0 $(THIS_TAG)~1)
  148. # Aria2 setup
  149. ARIA2 := aria2-$(VERSION)
  150. ARIA2_PREFIX := $(PWD)/$(ARIA2)
  151. ARIA2_DIST := $(PWD)/$(ARIA2)-osx-darwin$(BUILD)
  152. ARIA2_CONFFLAGS = \
  153. --enable-static \
  154. --disable-shared \
  155. --enable-metalink \
  156. --enable-bittorrent \
  157. --disable-nls \
  158. --with-appletls \
  159. --with-libgmp \
  160. --with-sqlite3 \
  161. --with-libz \
  162. --with-libexpat \
  163. --with-libcares \
  164. --with-libgcrypt \
  165. --with-libssh2 \
  166. --without-libuv \
  167. --without-gnutls \
  168. --without-openssl \
  169. --without-libnettle \
  170. --without-libxml2 \
  171. ARIA2_STATIC=yes
  172. ARIA2_DOCDIR = $(ARIA2_PREFIX)/share/doc/aria2
  173. ARIA2_DOCS = \
  174. $(ARIA2_DOCDIR)/AUTHORS \
  175. $(ARIA2_DOCDIR)/COPYING \
  176. $(ARIA2_DOCDIR)/NEWS
  177. ARIA2_CHANGELOG = $(ARIA2_DOCDIR)/Changelog
  178. # Yeah, inlined XML, go figure :p
  179. define ARIA2_DISTXML
  180. <?xml version="1.0" encoding="utf-8" standalone="no"?>
  181. <installer-gui-script minSpecVersion="1">
  182. <title>aria1 $(VERSION)</title>
  183. <welcome file="README.html"/>
  184. <pkg-ref id="aria2"/>
  185. <pkg-ref id="aria2.paths"/>
  186. <options customize="never" require-scripts="false" rootVolumeOnly="true"/>
  187. <volume-check>
  188. <allowed-os-versions>
  189. <os-version min="10.7"/>
  190. </allowed-os-versions>
  191. </volume-check>
  192. <domains enable_anywhere="false" enable_currentUserHome="false" enable_localSystem="true"/>
  193. <choices-outline>
  194. <line choice="default">
  195. <line choice="aria2"/>
  196. <line choice="aria2.paths"/>
  197. </line>
  198. </choices-outline>
  199. <choice id="default"/>
  200. <choice id="aria2" visible="false">
  201. <pkg-ref id="aria2"/>
  202. </choice>
  203. <choice id="aria2.paths" visible="false">
  204. <pkg-ref id="aria2.paths"/>
  205. </choice>
  206. <pkg-ref id="aria2" version="$(VERSION)" onConclusion="none">out.pkg</pkg-ref>
  207. <pkg-ref id="aria2.paths" version="$(VERSION)" onConclusion="none">paths.pkg</pkg-ref>
  208. </installer-gui-script>
  209. endef
  210. export ARIA2_DISTXML
  211. # Detect numer of CPUs to be used with make -j
  212. CPUS = $(shell sysctl hw.ncpu | cut -d" " -f2)
  213. # default target
  214. all::
  215. all::
  216. @if test "x$(NON_RELEASE)" = "x" && !(git describe --tags --exact); then \
  217. echo 'Not on a release tag; override by defining NON_RELEASE!'; \
  218. exit 1; \
  219. fi
  220. # No dice without sphinx
  221. all::
  222. @if test "x$$(which sphinx-build)" = "x"; then \
  223. echo "sphinx-build not present"; \
  224. exit 1; \
  225. fi;
  226. deps::
  227. # All those .PRECIOUS files, because otherwise gmake will treat them as
  228. # intermediates and remove them when the build completes. Thanks gmake!
  229. .PRECIOUS: %.tar.gz
  230. %.tar.gz:
  231. curl -o $@ -A 'curl/0; like wget' -L \
  232. $($(basename $(basename $@))_url)
  233. .PRECIOUS: %.check
  234. %.check: %.tar.gz
  235. @if test "$$(shasum -a1 $< | awk '{print $$1}')" != "$($(basename $@)_hash)"; then \
  236. echo "Invalid $@ hash"; \
  237. rm -f $<; \
  238. exit 1; \
  239. fi;
  240. touch $@
  241. .PRECIOUS: %.stamp
  242. %.stamp: %.tar.gz %.check
  243. tar xf $<
  244. mv $(basename $@)-$($(basename $@)_version) $(basename $@)
  245. touch $@
  246. .PRECIOUS: cares.stamp
  247. cares.stamp: cares.tar.gz cares.check
  248. tar xf $<
  249. mv c-ares-$($(basename $@)_version) $(basename $@)
  250. touch $@
  251. .PRECIOUS: libgpgerror.stamp
  252. libgpgerror.stamp: libgpgerror.tar.gz libgpgerror.check
  253. tar xf $<
  254. mv libgpg-error-$($(basename $@)_version) $(basename $@)
  255. touch $@
  256. # Using (NON)ARCH_template kinda stinks, but real multi-target pattern rules
  257. # only exist in feverish dreams.
  258. define NONARCH_template
  259. $(1).build: $(1).x86_64.build
  260. deps:: $(1).build
  261. endef
  262. .PRECIOUS: zlib.%.build
  263. zlib.%.build: zlib.stamp
  264. $(eval BASE := $(basename $<))
  265. $(eval DEST := $(basename $@))
  266. $(eval ARCH := $(subst .,,$(suffix $(DEST))))
  267. rsync -a $(BASE)/ $(DEST)
  268. ( cd $(DEST) && ./configure \
  269. --static --prefix=$(PWD)/arch \
  270. )
  271. $(MAKE) -C $(DEST) -sj$(CPUS) CFLAGS="$(CFLAGS) $(LTO_FLAGS) -arch $(ARCH)"
  272. $(MAKE) -C $(DEST) -sj$(CPUS) CFLAGS="$(CFLAGS) $(LTO_FLAGS) -arch $(ARCH)" check
  273. $(MAKE) -C $(DEST) -s install
  274. touch $@
  275. $(foreach lib,$(NONARCHLIBS),$(eval $(call NONARCH_template,$(lib))))
  276. define ARCH_template
  277. .PRECIOUS: $(1).%.build
  278. $(1).%.build: $(1).stamp
  279. $$(eval DEST := $$(basename $$@))
  280. $$(eval ARCH := $$(subst .,,$$(suffix $$(DEST))))
  281. mkdir -p $$(DEST)
  282. ( cd $$(DEST) && ../$(1)/configure \
  283. --enable-static --disable-shared \
  284. --prefix=$(PWD)/arch \
  285. $$($(1)_confflags) \
  286. CFLAGS="$$(CFLAGS) $$($(1)_cflags) -arch $$(ARCH)" \
  287. CXXFLAGS="$$(CXXFLAGS) $$($(1)_cxxflags) -arch $$(ARCH) -std=c++11" \
  288. LDFLAGS="$(LDFLAGS) $$($(1)_ldflags)" \
  289. PKG_CONFIG_PATH=$$(PWD)/arch/lib/pkgconfig \
  290. )
  291. $$(MAKE) -C $$(DEST) -sj$(CPUS)
  292. if test -z '$$($(1)_nocheck)'; then $$(MAKE) -C $$(DEST) -sj$(CPUS) check; fi
  293. $$(MAKE) -C $$(DEST) -s install
  294. touch $$@
  295. $(1).build: $(1).x86_64.build
  296. deps:: $(1).build
  297. endef
  298. $(foreach lib,$(ARCHLIBS),$(eval $(call ARCH_template,$(lib))))
  299. .PRECIOUS: aria2.%.build
  300. aria2.%.build: zlib.%.build expat.%.build gmp.%.build cares.%.build sqlite.%.build libgpgerror.%.build libgcrypt.%.build libssh2.%.build cppunit.%.build
  301. $(eval DEST := $$(basename $$@))
  302. $(eval ARCH := $$(subst .,,$$(suffix $$(DEST))))
  303. mkdir -p $(DEST)
  304. ( cd $(DEST) && ../$(SRCDIR)/configure \
  305. --prefix=$(ARIA2_PREFIX) \
  306. --bindir=$(PWD)/$(DEST) \
  307. --sysconfdir=/etc \
  308. --with-cppunit-prefix=$(PWD)/arch \
  309. $(ARIA2_CONFFLAGS) \
  310. CFLAGS="$(CFLAGS) $(LTO_FLAGS) -arch $(ARCH) -I$(PWD)/arch/include" \
  311. CXXFLAGS="$(CXXFLAGS) $(LTO_FLAGS) -arch $(ARCH) -I$(PWD)/arch/include" \
  312. LDFLAGS="$(LDFLAGS) $(CXXFLAGS) $(LTO_FLAGS) -L$(PWD)/arch/lib" \
  313. PKG_CONFIG_PATH=$(PWD)/arch/lib/pkgconfig \
  314. )
  315. $(MAKE) -C $(DEST) -sj$(CPUS)
  316. $(MAKE) -C $(DEST) -sj$(CPUS) check
  317. # Check that the resulting executable is Position-independent (PIE)
  318. otool -hv $(DEST)/src/aria2c | grep -q PIE
  319. $(MAKE) -C $(DEST) -sj$(CPUS) install-strip
  320. touch $@
  321. aria2.build: aria2.x86_64.build
  322. mkdir -p $(ARIA2_PREFIX)/bin
  323. cp -f aria2.x86_64/aria2c $(ARIA2_PREFIX)/bin/aria2c
  324. arch -64 $(ARIA2_PREFIX)/bin/aria2c -v
  325. touch $@
  326. $(ARIA2_CHANGELOG): aria2.x86_64.build
  327. git log --pretty=fuller --date=short $(PREV_TAG)..HEAD > $@
  328. $(ARIA2_DOCS): aria2.x86_64.build
  329. cp -av $(SRCDIR)/$(@F) $@
  330. $(ARIA2_DIST).tar.bz2: aria2.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
  331. find $(ARIA2_PREFIX) -exec touch "{}" \;
  332. tar -cf $@ \
  333. --use-compress-program="bzip2 -9" \
  334. $(ARIA2)
  335. $(ARIA2_DIST).pkg: aria2.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
  336. find $(ARIA2_PREFIX) -exec touch "{}" \;
  337. pkgbuild \
  338. --root $(ARIA2) \
  339. --identifier aria2 \
  340. --version $(VERSION) \
  341. --install-location /usr/local/aria2 \
  342. --ownership recommended \
  343. out.pkg
  344. pkgbuild \
  345. --root $(SRCDIR)/osx-package/etc \
  346. --identifier aria2.paths \
  347. --version $(VERSION) \
  348. --install-location /etc \
  349. --ownership recommended \
  350. paths.pkg
  351. echo "$$ARIA2_DISTXML" > dist.xml
  352. productbuild \
  353. --distribution dist.xml \
  354. --resources $(ARIA2_PREFIX)/share/doc/aria2 \
  355. $@
  356. rm -rf out.pkg paths.pkg dist.xml
  357. $(ARIA2_DIST).dmg: $(ARIA2_DIST).pkg
  358. -rm -rf dmg
  359. mkdir -p dmg/Docs
  360. cp -av $(ARIA2_DIST).pkg dmg/aria2.pkg
  361. find $(ARIA2_PREFIX)/share/doc/aria2 -maxdepth 1 -type f -exec cp -av "{}" dmg/Docs \;
  362. rm -rf dmg/Docs/README dmg/Docs/README.rst
  363. cp $(SRCDIR)/osx-package/DS_Store dmg/.DS_Store
  364. hdiutil create $@.uncompressed \
  365. -srcfolder dmg \
  366. -volname "aria2 $(VERSION) Intel" \
  367. -ov
  368. hdiutil convert -format UDBZ -o $@ $@.uncompressed.dmg
  369. hdiutil flatten $@
  370. rm -rf $@.uncompressed.dmg dmg
  371. dist.build: $(ARIA2_DIST).tar.bz2 $(ARIA2_DIST).pkg $(ARIA2_DIST).dmg
  372. echo 'Build success: $(ARIA2_DIST)'
  373. touch $@
  374. all:: dist.build
  375. clean-dist:
  376. rm -rf $(ARIA2_DIST).tar.bz2 $(ARIA2_DIST).pkg $(ARIA2_DIST).dmg
  377. clean: clean-dist
  378. rm -rf *aria2*
  379. cleaner: clean
  380. rm -rf *.build *.check *.stamp $(ARCHLIBS) $(NONARCHLIBS) arch *.x86_64
  381. really-clean: cleaner
  382. rm -rf *.tar.*
  383. .PHONY: all multi clean-dist clean cleaner really-clean