makerelease-osx.mk 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  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 universal build (x86_64, i686) use instead:
  35. # - $ make universal
  36. #
  37. # To make an both builds use instead:
  38. # - $ make multi
  39. #
  40. # If you haven't checkout out a release tag, you need to specify NON_RELEASE.
  41. # $ export NON_RELEASE=1
  42. # to generate a dist with git commit
  43. # $ export NON_RELEASE=force
  44. # to force this script to behave like it was on a tag.
  45. #
  46. # Note: This Makefile expects to be called from a git clone of aria2.
  47. #
  48. # Note: In theory, everything can be build in parallel, however the sub-makes
  49. # will be called with an appropriate -j flag. Building the `deps` target in
  50. # parallel before a general make might be beneficial, as the dependencies
  51. # usually bottle-neck on the configure steps.
  52. #
  53. # Note: Of course, you need to have XCode with the command line tools
  54. # installed for this to work, aka. a working compiler...
  55. #
  56. # Note: We're locally building the dependencies here, static libraries only.
  57. # This is required, because when using brew or MacPorts, which also provide
  58. # dynamic libraries, the linker will pick up the dynamic versions, always,
  59. # with no way to instruct the linker otherwise.
  60. # If you're building aria2 just for yourself and your system, using brewed
  61. # libraries is fine as well.
  62. #
  63. # Note: This Makefile is riddled with mac-isms. It will not work on *nix.
  64. #
  65. # Note: The convoluted way to create separate arch builds and later merge them
  66. # with lipo is because of two things:
  67. # 1) Avoid patching c-ares, which hardcodes some sizes in its headers.
  68. # 2) Make it easy in the future to enable -flto (currently, -flto builds crash)
  69. #
  70. # Note: This Makefile uses resources from osx-package when creating the
  71. # *.pkg and *.dmg targets
  72. SHELL := bash
  73. # A bit awkward, but OSX doesn't have a proper `readlink -f`.
  74. SRCDIR := $(shell dirname $(lastword $(shell stat -f "%N %Y" $(lastword $(MAKEFILE_LIST)))))
  75. # Same as in script-helper, but a bit easier on the eye (but more error prone)
  76. # and Makefile compatible
  77. BASE_VERSION := $(shell grep AC_INIT $(SRCDIR)/configure.ac | cut -d'[' -f3 | cut -d']' -f1)
  78. ifeq ($(NON_RELEASE),)
  79. VERSION := $(BASE_VERSION)
  80. else
  81. ifeq ($(NON_RELEASE),force)
  82. VERSION := $(BASE_VERSION)
  83. else
  84. VERSION := $(subst release-,,$(shell git describe --tags))
  85. endif
  86. endif
  87. # Set up compiler.
  88. CC ?= cc
  89. export CC
  90. CXX ?= c++
  91. export CXX
  92. # Set up compiler/linker flags.
  93. OPTFLAGS ?= -Os
  94. CFLAGS ?= -mmacosx-version-min=10.7 $(OPTFLAGS)
  95. export CFLAGS
  96. CXXFLAGS ?= -mmacosx-version-min=10.7 $(OPTFLAGS)
  97. export CXXFLAGS
  98. LDFLAGS ?= -Wl,-dead_strip
  99. export LDFLAGS
  100. # Dependency versions
  101. zlib_version = 1.2.8
  102. zlib_hash = a4d316c404ff54ca545ea71a27af7dbc29817088
  103. zlib_url = http://zlib.net/zlib-$(zlib_version).tar.gz
  104. expat_version = 2.1.0
  105. expat_hash = b08197d146930a5543a7b99e871cba3da614f6f0
  106. expat_url = http://sourceforge.net/projects/expat/files/expat/$(expat_version)/expat-$(expat_version).tar.gz
  107. cares_version = 1.10.0
  108. cares_hash = e44e6575d5af99cb3a38461486e1ee8b49810eb5
  109. cares_url = http://c-ares.haxx.se/download/c-ares-$(cares_version).tar.gz
  110. cares_confflags = "--enable-optimize=$(OPTFLAGS)"
  111. sqlite_version = autoconf-3080200
  112. sqlite_hash = 6033ef603ce221d367c665477514d972ef1dc90e
  113. sqlite_url = http://sqlite.org/2013/sqlite-$(sqlite_version).tar.gz
  114. gmp_version = 5.1.3
  115. gmp_hash = b35928e2927b272711fdfbf71b7cfd5f86a6b165
  116. gmp_url = https://ftp.gnu.org/gnu/gmp/gmp-$(gmp_version).tar.bz2
  117. gmp_confflags = --disable-cxx --enable-assembly --with-pic
  118. gmp_confflags_x86_64 = --enable-fat
  119. cppunit_version = 1.12.1
  120. cppunit_hash = f1ab8986af7a1ffa6760f4bacf5622924639bf4a
  121. cppunit_url = http://sourceforge.net/projects/cppunit/files/cppunit/$(cppunit_version)/cppunit-$(cppunit_version).tar.gz
  122. # ARCHLIBS that can be template build
  123. ARCHLIBS = expat cares sqlite gmp cppunit
  124. # NONARCHLIBS that cannot be template build
  125. NONARCHLIBS = zlib
  126. # Tags
  127. THIS_TAG := $(shell git describe --abbrev=0 $$(git rev-list --tags --max-count=1))
  128. PREV_TAG := $(shell git describe --abbrev=0 $(THIS_TAG)~1)
  129. # Aria2 setup
  130. ARIA2 := aria2-$(VERSION)
  131. ARIA2_PREFIX := $(PWD)/$(ARIA2)
  132. ARIA2_DIST := $(PWD)/$(ARIA2)-osx-darwin
  133. ARIA2_CONFFLAGS = \
  134. --enable-static \
  135. --disable-shared \
  136. --enable-metalink \
  137. --enable-bittorrent \
  138. --disable-nls \
  139. --with-appletls \
  140. --with-libgmp \
  141. --with-sqlite3 \
  142. --with-libz \
  143. --with-libexpat \
  144. --with-libcares \
  145. --without-libuv \
  146. --without-gnutls \
  147. --without-openssl \
  148. --without-libnettle \
  149. --without-libgcrypt \
  150. --without-libxml2 \
  151. ARIA2_STATIC=yes
  152. ARIA2_DOCDIR = $(ARIA2_PREFIX)/share/doc/aria2
  153. ARIA2_DOCS = \
  154. $(ARIA2_DOCDIR)/AUTHORS \
  155. $(ARIA2_DOCDIR)/COPYING \
  156. $(ARIA2_DOCDIR)/NEWS
  157. ARIA2_CHANGELOG = $(ARIA2_DOCDIR)/Changelog
  158. # Yeah, inlined XML, go figure :p
  159. define ARIA2_DISTXML
  160. <?xml version="1.0" encoding="utf-8" standalone="no"?>
  161. <installer-gui-script minSpecVersion="1">
  162. <title>aria1 $(VERSION)</title>
  163. <welcome file="README.html"/>
  164. <pkg-ref id="aria2"/>
  165. <pkg-ref id="aria2.paths"/>
  166. <options customize="never" require-scripts="false" rootVolumeOnly="true"/>
  167. <volume-check>
  168. <allowed-os-versions>
  169. <os-version min="10.7"/>
  170. </allowed-os-versions>
  171. </volume-check>
  172. <domains enable_anywhere="false" enable_currentUserHome="false" enable_localSystem="true"/>
  173. <choices-outline>
  174. <line choice="default">
  175. <line choice="aria2"/>
  176. <line choice="aria2.paths"/>
  177. </line>
  178. </choices-outline>
  179. <choice id="default"/>
  180. <choice id="aria2" visible="false">
  181. <pkg-ref id="aria2"/>
  182. </choice>
  183. <choice id="aria2.paths" visible="false">
  184. <pkg-ref id="aria2.paths"/>
  185. </choice>
  186. <pkg-ref id="aria2" version="$(VERSION)" onConclusion="none">out.pkg</pkg-ref>
  187. <pkg-ref id="aria2.paths" version="$(VERSION)" onConclusion="none">paths.pkg</pkg-ref>
  188. </installer-gui-script>
  189. endef
  190. export ARIA2_DISTXML
  191. # Detect numer of CPUs to be used with make -j
  192. CPUS = $(shell sysctl hw.ncpu | cut -d" " -f2)
  193. # default target
  194. all::
  195. universal all::
  196. @if test "x$(NON_RELEASE)" = "x" && !(git describe --tags --exact); then \
  197. echo 'Not on a release tag; override by defining NON_RELEASE!'; \
  198. exit 1; \
  199. fi
  200. # No dice without sphinx
  201. universal all::
  202. @if test "x$$(which sphinx-build)" = "x"; then \
  203. echo "sphinx-build not present"; \
  204. exit 1; \
  205. fi;
  206. deps::
  207. # All those .PRECIOUS files, because otherwise gmake will treat them as
  208. # intermediates and remove them when the build completes. Thanks gmake!
  209. .PRECIOUS: %.tar.gz
  210. %.tar.gz:
  211. curl -o $@ -A 'curl/0; like wget' -L \
  212. $($(basename $(basename $@))_url)
  213. .PRECIOUS: %.check
  214. %.check: %.tar.gz
  215. @if test "$$(shasum -a1 $< | awk '{print $$1}')" != "$($(basename $@)_hash)"; then \
  216. echo "Invalid $@ hash"; \
  217. rm -f $<; \
  218. exit 1; \
  219. fi;
  220. touch $@
  221. .PRECIOUS: %.stamp
  222. %.stamp: %.tar.gz %.check
  223. tar xf $<
  224. mv $(basename $@)-$($(basename $@)_version) $(basename $@)
  225. touch $@
  226. .PRECIOUS: cares.stamp
  227. cares.stamp: cares.tar.gz cares.check
  228. tar xzf $<
  229. mv c-ares-$($(basename $@)_version) $(basename $@)
  230. touch $@
  231. # Using (NON)ARCH_template kinda stinks, but real multi-target pattern rules
  232. # only exist in feverish dreams.
  233. define NONARCH_template
  234. $(1).build: $(1).x86_64.build
  235. $(1).universal.build: $(1).x86_64.build $(1).i686.build
  236. deps:: $(1).build
  237. deps.universal:: $(1).universal.build
  238. endef
  239. .PRECIOUS: zlib.%.build
  240. zlib.%.build: zlib.stamp
  241. $(eval BASE := $(basename $<))
  242. $(eval DEST := $(basename $@))
  243. $(eval ARCH := $(subst .,,$(suffix $(DEST))))
  244. rsync -a $(BASE)/ $(DEST)
  245. ( cd $(DEST) && ./configure \
  246. --static --prefix=$(PWD)/$(ARCH) \
  247. )
  248. $(MAKE) -C $(DEST) -sj$(CPUS) CFLAGS="$(CFLAGS) -arch $(ARCH)"
  249. $(MAKE) -C $(DEST) -sj$(CPUS) CFLAGS="$(CFLAGS) -arch $(ARCH)" check
  250. $(MAKE) -C $(DEST) -s install
  251. touch $@
  252. $(foreach lib,$(NONARCHLIBS),$(eval $(call NONARCH_template,$(lib))))
  253. define ARCH_template
  254. .PRECIOUS: $(1).%.build
  255. $(1).%.build: $(1).stamp
  256. $$(eval DEST := $$(basename $$@))
  257. $$(eval ARCH := $$(subst .,,$$(suffix $$(DEST))))
  258. mkdir -p $$(DEST)
  259. ( cd $$(DEST) && ../$(1)/configure \
  260. --host=$$(ARCH)-apple-darwin11.4.2 \
  261. --build=$$(ARCH)-apple-darwin11.4.2 \
  262. --enable-static --disable-shared \
  263. --prefix=$$(PWD)/$$(ARCH) \
  264. $$($(1)_confflags) $$($(1)_confflags_$$(ARCH)) \
  265. CFLAGS="$$(CFLAGS) -arch $$(ARCH)" \
  266. CXXFLAGS="$$(CXXFLAGS) -arch $$(ARCH) -stdlib=libc++ -std=c++11" \
  267. )
  268. $$(MAKE) -C $$(DEST) -sj$(CPUS)
  269. $$(MAKE) -C $$(DEST) -sj$(CPUS) check
  270. $$(MAKE) -C $$(DEST) -s install
  271. touch $$@
  272. $(1).build: $(1).x86_64.build
  273. $(1).universal.build: $(1).x86_64.build $(1).i686.build
  274. deps:: $(1).build
  275. deps.universal:: $(1).universal.build
  276. endef
  277. $(foreach lib,$(ARCHLIBS),$(eval $(call ARCH_template,$(lib))))
  278. .PRECIOUS: aria2.%.build
  279. aria2.%.build: zlib.%.build expat.%.build gmp.%.build cares.%.build sqlite.%.build cppunit.%.build
  280. $(eval DEST := $$(basename $$@))
  281. $(eval ARCH := $$(subst .,,$$(suffix $$(DEST))))
  282. mkdir -p $(DEST)
  283. ( cd $(DEST) && ../$(SRCDIR)/configure \
  284. --prefix=$(ARIA2_PREFIX) \
  285. --bindir=$(PWD)/$(DEST) \
  286. --sysconfdir=/etc \
  287. --with-cppunit-prefix=$(PWD)/$(ARCH) \
  288. $(ARIA2_CONFFLAGS) \
  289. CFLAGS="$(CFLAGS) -arch $(ARCH) -I$(PWD)/$(ARCH)/include" \
  290. CXXFLAGS="$(CXXFLAGS) -arch $(ARCH) -I$(PWD)/$(ARCH)/include" \
  291. LDFLAGS="$(LDFLAGS) -L$(PWD)/$(ARCH)/lib" \
  292. PKG_CONFIG_PATH=$(PWD)/$(ARCH)/lib/pkgconfig \
  293. )
  294. $(MAKE) -C $(DEST) -sj$(CPUS) check
  295. # Check that the resulting executable is Position-independent (PIE)
  296. otool -hv $(DEST)/src/aria2c | grep -q PIE
  297. $(MAKE) -C $(DEST) -sj$(CPUS) install-strip
  298. touch $@
  299. aria2.build: aria2.x86_64.build
  300. mkdir -p $(ARIA2_PREFIX)/bin
  301. cp -f aria2.x86_64/aria2c $(ARIA2_PREFIX)/bin/aria2c
  302. arch -64 $(ARIA2_PREFIX)/bin/aria2c -v
  303. touch $@
  304. aria2.universal.build: aria2.x86_64.build aria2.i686.build
  305. mkdir -p $(ARIA2_PREFIX)/bin
  306. # Got two binaries now. Merge them into one universal binary and remove
  307. # the old ones.
  308. lipo \
  309. -arch x86_64 aria2.x86_64/aria2c \
  310. -arch i686 aria2.i686/aria2c \
  311. -create -output $(ARIA2_PREFIX)/bin/aria2c
  312. # Basic sanity check
  313. arch -64 $(ARIA2_PREFIX)/bin/aria2c -v
  314. arch -32 $(ARIA2_PREFIX)/bin/aria2c -v
  315. touch $@
  316. $(ARIA2_CHANGELOG): aria2.x86_64.build
  317. git log --pretty=fuller --date=short $(PREV_TAG)..HEAD > $@
  318. $(ARIA2_DOCS): aria2.x86_64.build
  319. cp -av $(SRCDIR)/$(@F) $@
  320. $(ARIA2_DIST).tar.bz2: aria2.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
  321. find $(ARIA2_PREFIX) -exec touch "{}" \;
  322. tar -cf $@ \
  323. --use-compress-program=bzip2 \
  324. --options='compression-level=9' \
  325. $(ARIA2)
  326. $(ARIA2_DIST).universal.tar.bz2: aria2.universal.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
  327. find $(ARIA2_PREFIX) -exec touch "{}" \;
  328. tar -cf $@ \
  329. --use-compress-program=bzip2 \
  330. --options='compression-level=9' \
  331. $(ARIA2)
  332. $(ARIA2_DIST).pkg: aria2.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
  333. find $(ARIA2_PREFIX) -exec touch "{}" \;
  334. pkgbuild \
  335. --root $(ARIA2) \
  336. --identifier aria2 \
  337. --version $(VERSION) \
  338. --install-location /usr/local/aria2 \
  339. --ownership recommended \
  340. out.pkg
  341. pkgbuild \
  342. --root $(SRCDIR)/osx-package/etc \
  343. --identifier aria2.paths \
  344. --version $(VERSION) \
  345. --install-location /etc \
  346. --ownership recommended \
  347. paths.pkg
  348. echo "$$ARIA2_DISTXML" > dist.xml
  349. productbuild \
  350. --distribution dist.xml \
  351. --resources $(ARIA2_PREFIX)/share/doc/aria2 \
  352. $@
  353. rm -rf out.pkg paths.pkg dist.xml
  354. $(ARIA2_DIST).universal.pkg: aria2.universal.build $(ARIA2_DOCS) $(ARIA2_CHANGELOG)
  355. find $(ARIA2_PREFIX) -exec touch "{}" \;
  356. pkgbuild \
  357. --root $(ARIA2) \
  358. --identifier aria2 \
  359. --version $(VERSION) \
  360. --install-location /usr/local/aria2 \
  361. --ownership recommended \
  362. out.pkg
  363. pkgbuild \
  364. --root $(SRCDIR)/osx-package/etc \
  365. --identifier aria2.paths \
  366. --version $(VERSION) \
  367. --install-location /etc \
  368. --ownership recommended \
  369. paths.pkg
  370. echo "$$ARIA2_DISTXML" > dist.xml
  371. productbuild \
  372. --distribution dist.xml \
  373. --resources $(ARIA2_PREFIX)/share/doc/aria2 \
  374. $@
  375. rm -rf out.pkg paths.pkg dist.xml
  376. $(ARIA2_DIST).dmg: $(ARIA2_DIST).pkg
  377. -rm -rf dmg
  378. mkdir -p dmg/Docs
  379. cp -av $(ARIA2_DIST).pkg dmg/aria2.pkg
  380. find $(ARIA2_PREFIX)/share/doc/aria2 -type f -depth 1 -exec cp -av "{}" dmg/Docs \;
  381. rm -rf dmg/Docs/README dmg/Docs/README.rst
  382. cp $(SRCDIR)/osx-package/DS_Store dmg/.DS_Store
  383. hdiutil create $@.uncompressed \
  384. -srcfolder dmg \
  385. -volname "aria2 $(VERSION) Intel" \
  386. -ov
  387. hdiutil convert -format UDBZ -o $@ $@.uncompressed.dmg
  388. hdiutil flatten $@
  389. rm -rf $@.uncompressed.dmg dmg
  390. $(ARIA2_DIST).universal.dmg: $(ARIA2_DIST).universal.pkg
  391. -rm -rf dmg
  392. mkdir -p dmg/Docs
  393. cp -av $(ARIA2_DIST).universal.pkg dmg/aria2.pkg
  394. find $(ARIA2_PREFIX)/share/doc/aria2 -type f -depth 1 -exec cp -av "{}" dmg/Docs \;
  395. rm -rf dmg/Docs/README dmg/Docs/README.rst
  396. cp $(SRCDIR)/osx-package/DS_Store dmg/.DS_Store
  397. hdiutil create $@.uncompressed \
  398. -srcfolder dmg \
  399. -volname "aria2 $(VERSION) Intel Universal" \
  400. -ov
  401. hdiutil convert -format UDBZ -o $@ $@.uncompressed.dmg
  402. hdiutil flatten $@
  403. rm -rf $@.uncompressed.dmg dmg
  404. dist.build: $(ARIA2_DIST).tar.bz2 $(ARIA2_DIST).pkg $(ARIA2_DIST).dmg
  405. echo 'Build success: $(ARIA2_DIST)'
  406. touch $@
  407. dist.universal.build: $(ARIA2_DIST).universal.tar.bz2 $(ARIA2_DIST).universal.pkg $(ARIA2_DIST).universal.dmg
  408. echo 'Build success: $(ARIA2_DIST)'
  409. touch $@
  410. all:: dist.build
  411. universal:: dist.universal.build
  412. multi: all universal
  413. clean-dist:
  414. rm -rf $(ARIA2_DIST).tar.bz2 $(ARIA2_DIST).pkg $(ARIA2_DIST).dmg
  415. clean: clean-dist
  416. rm -rf *aria2*
  417. cleaner: clean
  418. rm -rf *.build *.check *.stamp $(ARCHLIBS) $(NONARCHLIBS) *x86_64* *i686*
  419. really-clean: cleaner
  420. rm -rf *.tar.*
  421. .PHONY: all universal multi clean-dist clean cleaner really-clean