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.

1100 lines
45KB

  1. # This file is part of MXE. See LICENSE.md for licensing information.
  2. MAKEFILE := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
  3. TOP_DIR := $(patsubst %/,%,$(dir $(MAKEFILE)))
  4. EXT_DIR := $(TOP_DIR)/ext
  5. # GNU Make Standard Library (https://gmsl.sourceforge.io/)
  6. # See docs/gmsl.html for further information
  7. include $(EXT_DIR)/gmsl
  8. MXE_TRIPLETS := i686-w64-mingw32 x86_64-w64-mingw32
  9. MXE_LIB_TYPES := static shared
  10. MXE_TARGET_LIST := $(strip $(foreach TRIPLET,$(MXE_TRIPLETS),\
  11. $(addprefix $(TRIPLET).,$(MXE_LIB_TYPES))))
  12. MXE_TARGETS := i686-w64-mingw32.static
  13. .DEFAULT_GOAL := all-filtered
  14. DEFAULT_MAX_JOBS := 6
  15. PRINTF_COL_1_WIDTH := 13
  16. SOURCEFORGE_MIRROR := downloads.sourceforge.net
  17. MXE_MIRROR := https://mirror.mxe.cc/pkg
  18. PKG_MIRROR := https://s3.amazonaws.com/mxe-pkg
  19. PKG_CDN := http://d1yihgixbnrglp.cloudfront.net
  20. GITLAB_BACKUP := https://gitlab.com/starius/mxe-backup2/raw/master
  21. # reorder as required, ensuring final one is a http fallback
  22. MIRROR_SITES := GITLAB_BACKUP MXE_MIRROR PKG_MIRROR PKG_CDN
  23. PWD := $(shell pwd)
  24. SHELL := bash
  25. MXE_TMP := $(PWD)
  26. BUILD_CC := $(shell (gcc --help >/dev/null 2>&1 && echo gcc) || (clang --help >/dev/null 2>&1 && echo clang))
  27. BUILD_CXX := $(shell (g++ --help >/dev/null 2>&1 && echo g++) || (clang++ --help >/dev/null 2>&1 && echo clang++))
  28. DATE := $(shell gdate --help >/dev/null 2>&1 && echo g)date
  29. INSTALL := $(shell ginstall --help >/dev/null 2>&1 && echo g)install
  30. LIBTOOL := $(shell glibtool --help >/dev/null 2>&1 && echo g)libtool
  31. LIBTOOLIZE := $(shell glibtoolize --help >/dev/null 2>&1 && echo g)libtoolize
  32. OPENSSL := openssl
  33. PATCH := $(shell gpatch --help >/dev/null 2>&1 && echo g)patch
  34. PYTHON2 := $(or $(shell ([ `python -c "import sys; print('{0[0]}'.format(sys.version_info))"` == 2 ] && echo python) 2>/dev/null || \
  35. which python2 2>/dev/null || \
  36. which python2.7 2>/dev/null), \
  37. $(warning Warning: python v2 not found (or default python changed to v3))\
  38. $(shell touch check-requirements-failed))
  39. SED := $(shell gsed --help >/dev/null 2>&1 && echo g)sed
  40. SORT := $(shell gsort --help >/dev/null 2>&1 && echo g)sort
  41. DEFAULT_UA := $(shell wget --version | $(SED) -n 's,GNU \(Wget\) \([0-9.]*\).*,\1/\2,p')
  42. WGET_TOOL = wget
  43. WGET = $(WGET_TOOL) --user-agent='$(or $($(1)_UA),$(DEFAULT_UA))'
  44. REQUIREMENTS := autoconf automake autopoint bash bison bzip2 flex \
  45. $(BUILD_CC) $(BUILD_CXX) gperf intltoolize $(LIBTOOL) \
  46. $(LIBTOOLIZE) lzip $(MAKE) $(OPENSSL) $(PATCH) $(PERL) python \
  47. ruby $(SED) $(SORT) unzip wget xz 7za gdk-pixbuf-csource
  48. PREFIX := $(PWD)/usr
  49. LOG_DIR := $(PWD)/log
  50. GITS_DIR := $(PWD)/gits
  51. GIT_HEAD := $(shell git rev-parse HEAD)
  52. TIMESTAMP := $(shell date +%Y%m%d_%H%M%S)
  53. PKG_DIR := $(PWD)/pkg
  54. TMP_DIR = $(MXE_TMP)/tmp-$(1)
  55. BUILD := $(shell '$(EXT_DIR)/config.guess')
  56. PATH := $(PREFIX)/$(BUILD)/bin:$(PREFIX)/bin:$(shell echo $$PATH | $(SED) -e 's,:\.$$,,' -e 's,\.:,,g')
  57. # set to empty or $(false) to disable stripping
  58. STRIP_TOOLCHAIN := $(true)
  59. STRIP_LIB := $(false)
  60. STRIP_EXE := $(true)
  61. # disable by setting MXE_USE_CCACHE
  62. MXE_USE_CCACHE := mxe
  63. MXE_CCACHE_DIR := $(PWD)/.ccache
  64. MXE_CCACHE_BASE_DIR := $(PWD)
  65. # define some whitespace variables
  66. define newline
  67. endef
  68. \n := $(newline)
  69. comma := ,
  70. null :=
  71. space := $(null) $(null)
  72. repeat = $(subst x,$(1),$(subst $(space),,$(call int_encode,$(2))))
  73. PLUGIN_HEADER = $(info $(shell printf '%-$(PRINTF_COL_1_WIDTH)s %s\n' [plugin] $(dir $(lastword $(MAKEFILE_LIST)))))
  74. MXE_DISABLE_DOC_OPTS = \
  75. ac_cv_prog_HAVE_DOXYGEN="false" \
  76. --enable-doc=no \
  77. --enable-gtk-doc=no \
  78. --enable-gtk-doc-html=no \
  79. --enable-gtk-doc-pdf=no \
  80. --{docdir,infodir,mandir,with-html-dir}='$(BUILD_DIR).sink' \
  81. --disable-doxygen
  82. MXE_CONFIGURE_OPTS = \
  83. --host='$(TARGET)' \
  84. --build='$(BUILD)' \
  85. --prefix='$(PREFIX)/$(TARGET)' \
  86. $(if $(BUILD_STATIC), \
  87. --enable-static --disable-shared , \
  88. --disable-static --enable-shared ) \
  89. $(MXE_DISABLE_DOC_OPTS)
  90. PKG_CONFIGURE_OPTS = \
  91. $(_$(PKG)_CONFIGURE_OPTS) \
  92. $($(PKG)_CONFIGURE_OPTS)
  93. # GCC threads and exceptions
  94. MXE_GCC_THREADS = \
  95. $(if $(findstring win32,$(or $(TARGET),$(1))),win32,posix)
  96. # allowed exception handling for targets
  97. # default (first item) and alternate, revisit if gcc/mingw-w64 change defaults
  98. i686-w64-mingw32_EH := sjlj dw2
  99. x86_64-w64-mingw32_EH := seh sjlj
  100. # functions to determine exception handling from user-specified target
  101. # $(or $(TARGET),$(1)) allows use as both function and inline snippet
  102. TARGET_EH_LIST = $($(firstword $(call split,.,$(or $(TARGET),$(1))))_EH)
  103. DEFAULT_EH = $(firstword $(TARGET_EH_LIST))
  104. GCC_EXCEPTIONS = \
  105. $(lastword $(DEFAULT_EH) \
  106. $(filter $(TARGET_EH_LIST),$(call split,.,$(or $(TARGET),$(1)))))
  107. MXE_GCC_EXCEPTION_OPTS = \
  108. $(if $(call seq,sjlj,$(GCC_EXCEPTIONS)),--enable-sjlj-exceptions) \
  109. $(if $(call seq,dw2,$(GCC_EXCEPTIONS)),--disable-sjlj-exceptions)
  110. # Append these to the "make" and "make install" steps of autotools packages
  111. # in order to neither build nor install unwanted binaries, manpages,
  112. # infopages and API documentation (reduces build time and disk space usage).
  113. # NOTE: We don't include bin_SCRIPTS (and variations), since many packages
  114. # install files such as pcre-config (which we do want to be installed).
  115. MXE_DISABLE_PROGRAMS = \
  116. dist_bin_SCRIPTS= \
  117. bin_PROGRAMS= \
  118. sbin_PROGRAMS= \
  119. noinst_PROGRAMS= \
  120. check_PROGRAMS=
  121. MXE_DISABLE_DOCS = \
  122. man_MANS= \
  123. man1_MANS= \
  124. man2_MANS= \
  125. man3_MANS= \
  126. man4_MANS= \
  127. man5_MANS= \
  128. man6_MANS= \
  129. man7_MANS= \
  130. man8_MANS= \
  131. man9_MANS= \
  132. dist_man_MANS= \
  133. dist_man1_MANS= \
  134. dist_man2_MANS= \
  135. dist_man3_MANS= \
  136. dist_man4_MANS= \
  137. dist_man5_MANS= \
  138. dist_man6_MANS= \
  139. dist_man7_MANS= \
  140. dist_man8_MANS= \
  141. dist_man9_MANS= \
  142. nodist_man_MANS= \
  143. nodist_man1_MANS= \
  144. nodist_man2_MANS= \
  145. nodist_man3_MANS= \
  146. nodist_man4_MANS= \
  147. nodist_man5_MANS= \
  148. nodist_man6_MANS= \
  149. nodist_man7_MANS= \
  150. nodist_man8_MANS= \
  151. nodist_man9_MANS= \
  152. notrans_dist_man_MANS= \
  153. MANLINKS= \
  154. info_TEXINFOS= \
  155. doc_DATA= \
  156. dist_doc_DATA= \
  157. html_DATA= \
  158. dist_html_DATA=
  159. MXE_DISABLE_CRUFT = $(MXE_DISABLE_PROGRAMS) $(MXE_DISABLE_DOCS)
  160. MAKE_SHARED_FROM_STATIC = \
  161. '$(TOP_DIR)/tools/make-shared-from-static' \
  162. $(if $(findstring mingw,$(TARGET)),--windowsdll) \
  163. --ar '$(TARGET)-ar' \
  164. --ld '$(TARGET)-gcc' \
  165. --install '$(INSTALL)' \
  166. --libdir '$(PREFIX)/$(TARGET)/lib' \
  167. --bindir '$(PREFIX)/$(TARGET)/bin'
  168. define AUTOTOOLS_CONFIGURE
  169. cd '$(BUILD_DIR)' && $(SOURCE_DIR)/configure \
  170. $(MXE_CONFIGURE_OPTS)
  171. endef
  172. define AUTOTOOLS_MAKE
  173. $(MAKE) -C '$(BUILD_DIR)' -j '$(JOBS)' $(MXE_DISABLE_DOCS)
  174. $(MAKE) -C '$(BUILD_DIR)' -j 1 install $(MXE_DISABLE_DOCS)
  175. endef
  176. define AUTOTOOLS_BUILD
  177. $(AUTOTOOLS_CONFIGURE)
  178. $(AUTOTOOLS_MAKE)
  179. endef
  180. # include github related functions
  181. include $(PWD)/mxe.github.mk
  182. # shared lib preload to disable networking, enable faketime etc
  183. PRELOAD_VARS := LD_PRELOAD DYLD_FORCE_FLAT_NAMESPACE DYLD_INSERT_LIBRARIES
  184. # use a minimal whitelist of safe environment variables
  185. # basic working shell environment and mxe variables
  186. # see http://www.linuxfromscratch.org/lfs/view/stable/chapter04/settingenvironment.html
  187. ENV_WHITELIST := EDITOR HOME LANG LC_% PATH %PROXY %proxy PS1 TERM
  188. ENV_WHITELIST += MAKE% MXE% $(PRELOAD_VARS) WINEPREFIX
  189. # OS/Distro related issues - "unsafe" but practical
  190. # 1. https://github.com/mxe/mxe/issues/697
  191. ENV_WHITELIST += ACLOCAL_PATH LD_LIBRARY_PATH
  192. unexport $(filter-out $(ENV_WHITELIST),$(shell env | cut -d '=' -f1))
  193. SHORT_PKG_VERSION = \
  194. $(word 1,$(subst ., ,$($(1)_VERSION))).$(word 2,$(subst ., ,$($(1)_VERSION)))
  195. UNPACK_ARCHIVE = \
  196. $(if $(filter %.tgz, $(1)),tar xzf '$(1)', \
  197. $(if $(filter %.tar.gz, $(1)),tar xzf '$(1)', \
  198. $(if $(filter %.tar.Z, $(1)),tar xzf '$(1)', \
  199. $(if $(filter %.tbz2, $(1)),tar xjf '$(1)', \
  200. $(if $(filter %.tar.bz2, $(1)),tar xjf '$(1)', \
  201. $(if $(filter %.tar.lz, $(1)),lzip -dc '$(1)'| tar xf -, \
  202. $(if $(filter %.tar.lzma,$(1)),xz -dc -F lzma '$(1)' | tar xf -, \
  203. $(if $(filter %.txz, $(1)),xz -dc '$(1)' | tar xf -, \
  204. $(if $(filter %.tar.xz, $(1)),xz -dc '$(1)' | tar xf -, \
  205. $(if $(filter %.7z, $(1)),7za x '$(1)', \
  206. $(if $(filter %.zip, $(1)),unzip -q '$(1)', \
  207. $(if $(filter %.deb, $(1)),ar x '$(1)' && tar xf data.tar*, \
  208. $(error Unknown archive format: $(1))))))))))))))
  209. UNPACK_PKG_ARCHIVE = \
  210. $(call UNPACK_ARCHIVE,$(PKG_DIR)/$($(1)_FILE))
  211. # some shortcuts for awareness of MXE_PLUGIN_DIRS
  212. # all files for extension plugins will be considered for outdated checks
  213. PKG_MAKEFILES = $(realpath $(sort $(wildcard $(addsuffix /$(1).mk, $(MXE_PLUGIN_DIRS)))))
  214. PKG_TESTFILES = $(realpath $(sort $(wildcard $(addsuffix /$(1)-test*, $(MXE_PLUGIN_DIRS)))))
  215. # allow packages to specify a list of zero or more patches
  216. PKG_PATCHES = $(if $(findstring undefined,$(origin $(1)_PATCHES)), \
  217. $(realpath $(sort $(wildcard $(addsuffix /$(1)-[0-9]*.patch, $(MXE_PLUGIN_DIRS))))) \
  218. $(else), \
  219. $($(1)_PATCHES))
  220. define PREPARE_PKG_SOURCE
  221. $(if $($(1)_SOURCE_TREE),\
  222. ln -si '$(realpath $($(1)_SOURCE_TREE))' '$(2)/$($(1)_SUBDIR)'
  223. $(else),\
  224. cd '$(2)' && $(call UNPACK_PKG_ARCHIVE,$(1))
  225. cd '$(2)/$($(1)_SUBDIR)'
  226. $(foreach PKG_PATCH,$($(1)_PATCHES),
  227. (cd '$(2)/$($(1)_SUBDIR)' && $(PATCH) -p1 -u) < $(PKG_PATCH))
  228. )
  229. endef
  230. PKG_CHECKSUM = \
  231. $(OPENSSL) dgst -sha256 '$(or $(2),$(PKG_DIR)/$($(1)_FILE))' 2>/dev/null | $(SED) -n 's,^.*\([0-9a-f]\{64\}\)$$,\1,p'
  232. CHECK_PKG_ARCHIVE = \
  233. $(if $($(1)_SOURCE_TREE),\
  234. $(PRINTF_FMT) '[local]' '$(1)' '$($(1)_SOURCE_TREE)' | $(RTRIM)\
  235. $(else),$(if $(SKIP_CHECHSUM),true, \
  236. [ '$($(1)_CHECKSUM)' == "`$$(call PKG_CHECKSUM,$(1),$(2))`" ]\
  237. ))
  238. ESCAPE_PKG = \
  239. echo '$($(1)_FILE)' | perl -lpe 's/([^A-Za-z0-9])/sprintf("%%%02X", ord($$$$1))/seg'
  240. BACKUP_DOWNLOAD = \
  241. (echo "MXE Warning! Downloading $(1) from backup." >&2 && \
  242. ($(foreach SITE,$(MIRROR_SITES), \
  243. $(WGET) -O '$(TMP_FILE)' $($(SITE))/`$(call ESCAPE_PKG,$(1))`_$($(1)_CHECKSUM) || ) false))
  244. DOWNLOAD_PKG_ARCHIVE = \
  245. $(eval TMP_FILE := $(PKG_DIR)/.tmp-$($(1)_FILE)) \
  246. $(if $($(1)_SOURCE_TREE),\
  247. true\
  248. $(else),\
  249. mkdir -p '$(PKG_DIR)' && ( \
  250. ($(WGET) -T 30 -t 3 -O '$(TMP_FILE)' '$($(1)_URL)' && \
  251. $(call CHECK_PKG_ARCHIVE,$(1),'$(TMP_FILE)')) \
  252. $(if $($(1)_URL_2), \
  253. || (echo "MXE Warning! Downloading $(1) from second URL." >&2 && \
  254. $(WGET) -T 30 -t 3 -O '$(TMP_FILE)' '$($(1)_URL_2)' && \
  255. $(call CHECK_PKG_ARCHIVE,$(1),'$(TMP_FILE)'))) \
  256. $(if $(MXE_NO_BACKUP_DL),, \
  257. || $(BACKUP_DOWNLOAD)) \
  258. ) && cat '$(TMP_FILE)' \
  259. $(if $($(1)_FIX_GZIP), \
  260. | gzip -d | gzip -9n, \
  261. ) \
  262. > '$(PKG_DIR)/$($(1)_FILE)' && \
  263. $(if $(CREATE_SUFFIXED_ARCHIVE),cp '$(PKG_DIR)/$($(1)_FILE)' '$(PKG_DIR)/$($(1)_FILE)_$($(1)_CHECKSUM)' &&) \
  264. rm '$(TMP_FILE)' || \
  265. ( echo; \
  266. echo 'Download failed!'; \
  267. echo; \
  268. rm -f '$(PKG_DIR)/$($(1)_FILE)' '$(TMP_FILE)'; )\
  269. )
  270. # open issue from 2002:
  271. # https://savannah.gnu.org/bugs/?712
  272. ifneq ($(words $(PWD)),1)
  273. $(error GNU Make chokes on paths with spaces)
  274. endif
  275. # dollar signs also cause troubles
  276. ifneq (,$(findstring $$,$(PWD)))
  277. $(error GNU Make chokes on paths with dollar signs)
  278. endif
  279. ifeq ($(IGNORE_SETTINGS),yes)
  280. $(info [ignore settings.mk])
  281. else ifeq ($(wildcard $(PWD)/settings.mk),$(PWD)/settings.mk)
  282. include $(PWD)/settings.mk
  283. else
  284. $(info [create settings.mk])
  285. $(shell { \
  286. echo '# This is a template of configuration file for MXE. See'; \
  287. echo '# docs/index.html for more extensive documentations.'; \
  288. echo; \
  289. echo '# This variable controls the number of compilation processes'; \
  290. echo '# within one package ("intra-package parallelism").'; \
  291. echo '#JOBS := $(JOBS)'; \
  292. echo; \
  293. echo '# This variable controls where intermediate files are created'; \
  294. echo '# this is necessary when compiling inside a virtualbox shared'; \
  295. echo '# directory. Some commands like strip fail in there with Protocol error'; \
  296. echo '# default is the current directory'; \
  297. echo '#MXE_TMP := /tmp'; \
  298. echo; \
  299. echo '# This variable controls the targets that will build.'; \
  300. echo '#MXE_TARGETS := $(MXE_TARGET_LIST)'; \
  301. echo; \
  302. echo '# This variable controls which plugins are in use.'; \
  303. echo '# See plugins/README.md for further information.'; \
  304. echo '#override MXE_PLUGIN_DIRS += plugins/apps plugins/native'; \
  305. echo; \
  306. echo '# This variable controls the download mirror for SourceForge,'; \
  307. echo '# when it is used. Enabling the value below means auto.'; \
  308. echo '#SOURCEFORGE_MIRROR := downloads.sourceforge.net'; \
  309. echo; \
  310. echo '# The three lines below makes `make` build these "local'; \
  311. echo '# packages" instead of all packages.'; \
  312. echo '#LOCAL_PKG_LIST := boost curl file flac lzo pthreads vorbis wxwidgets'; \
  313. echo '#.DEFAULT_GOAL := local-pkg-list'; \
  314. echo '#local-pkg-list: $$(LOCAL_PKG_LIST)'; \
  315. } >'$(PWD)/settings.mk')
  316. endif
  317. ifneq ($(LOCAL_PKG_LIST),)
  318. .DEFAULT_GOAL := local-pkg-list
  319. $(info [pkg-list] $(LOCAL_PKG_LIST))
  320. endif
  321. # Numeric min and max list functions
  322. LIST_NMAX = $(shell echo '$(strip $(1))' | tr ' ' '\n' | sort -n | tail -1)
  323. LIST_NMIN = $(shell echo '$(strip $(1))' | tr ' ' '\n' | sort -n | head -1)
  324. NPROCS := $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 1)
  325. JOBS := $(call LIST_NMIN, $(DEFAULT_MAX_JOBS) $(NPROCS))
  326. # Core packages.
  327. override MXE_PLUGIN_DIRS := $(realpath $(TOP_DIR)/src) $(MXE_PLUGIN_DIRS)
  328. # Build native requirements for certain systems
  329. OS_SHORT_NAME := $(call lc,$(shell lsb_release -sc 2>/dev/null || uname -s))
  330. override MXE_PLUGIN_DIRS += $(realpath $(TOP_DIR)/plugins/native/$(OS_SHORT_NAME))
  331. .PHONY: check-requirements
  332. define CHECK_REQUIREMENT
  333. @if ! ( $(1) --help || $(1) help ) &>/dev/null; then \
  334. echo 'Missing requirement: $(1)'; \
  335. touch check-requirements-failed; \
  336. fi
  337. endef
  338. define CHECK_REQUIREMENT_VERSION
  339. @if ! $(1) --version | head -1 | grep ' \($(2)\)$$' >/dev/null; then \
  340. echo 'Wrong version of requirement: $(1)'; \
  341. touch check-requirements-failed; \
  342. fi
  343. endef
  344. %/.gitkeep:
  345. +@mkdir -p '$(dir $@)'
  346. @touch '$@'
  347. check-requirements: $(PREFIX)/installed/check-requirements
  348. $(PREFIX)/installed/check-requirements: $(MAKEFILE) | $(PREFIX)/installed/.gitkeep
  349. @echo '[check reqs]'
  350. $(foreach REQUIREMENT,$(REQUIREMENTS),$(call CHECK_REQUIREMENT,$(REQUIREMENT)))
  351. $(call CHECK_REQUIREMENT_VERSION,autoconf,2\.6[8-9]\|2\.[7-9][0-9])
  352. $(call CHECK_REQUIREMENT_VERSION,automake,1\.11\.[3-9]\|1\.[1-9][2-9]\(\.[0-9]\+\)\?)
  353. @if [ -e check-requirements-failed ]; then \
  354. echo; \
  355. echo 'Please have a look at "docs/index.html" to ensure'; \
  356. echo 'that your system meets all requirements.'; \
  357. echo; \
  358. rm check-requirements-failed; \
  359. exit 1; \
  360. fi
  361. @touch '$@'
  362. .PHONY: print-git-oneline
  363. print-git-oneline: $(PREFIX)/installed/print-git-oneline-$(GIT_HEAD)
  364. $(PREFIX)/installed/print-git-oneline-$(GIT_HEAD): | $(PREFIX)/installed/.gitkeep
  365. @git log --pretty=tformat:'[git-log] %h %s' -1 | cat
  366. @rm -f '$(PREFIX)/installed/print-git-oneline-'*
  367. @touch '$@'
  368. # Common dependency lists for `make` prerequisites and `build-pkg`
  369. # - `make` considers only explicit normal deps to trigger rebuilds
  370. # - packages can add themselves to implicit MXE_REQS_PKGS in the case
  371. # of a tool like `patch` which may be outdated on some systems
  372. # - downloads and `build-pkg` use both explicit and implicit deps
  373. # - don't depend on `disabled` rules but do depend on virtual pkgs
  374. # cross libraries depend on virtual toolchain package, variable used
  375. # in `cleanup-deps-style` rule below
  376. CROSS_COMPILER := cc
  377. # set reqs and bootstrap variables to recursive so pkgs can add themselves
  378. # CROSS_COMPILER depends (order-only) on MXE_REQS_PKGS
  379. # all depend (order-only) on BOOTSTRAP_PKGS
  380. # BOOTSTRAP_PKGS may be prefixed with $(BUILD)~
  381. MXE_REQS_PKGS =
  382. BOOTSTRAP_PKGS =
  383. # warning about switching from `gcc` to `cc`
  384. $(if $(and $(filter gcc,$(LOCAL_PKG_LIST)$(MAKECMDGOALS)),\
  385. $(call seq,1,$(words $(LOCAL_PKG_LIST)$(MAKECMDGOALS)))),\
  386. $(info == gcc is now a dependency of virtual toolchain package cc) \
  387. $(info $(call repeat,$(space),6)- cc will build gcc, pkgconf, and other core toolchain packages)\
  388. $(info $(call repeat,$(space),6)- please update scripts accordingly (ignore if you are building gcc alone))\
  389. $(info ))
  390. # distinguish between deliberately empty rules and disabled ones
  391. # used in build-matrix
  392. VIRTUAL_PKG_TYPES := source-only meta
  393. # used in deps rules and build-pkg
  394. BUILD_PKG_TYPES := meta
  395. # used to avoid unpacking archives when $(PKG)_FILE can't be unset
  396. SCRIPT_PKG_TYPES := script
  397. # all pkgs have (implied) order-only dependencies on MXE_CONF_PKGS.
  398. MXE_CONF_PKGS := mxe-conf
  399. # autotools/cmake are generally always required, but separate them
  400. # for the case of `make gcc` which should only build real deps.
  401. AUTOTOOLS_PKGS := $(filter-out $(MXE_CONF_PKGS) %autotools autoconf automake libtool, \
  402. $(sort $(basename $(notdir \
  403. $(shell grep -l 'auto[conf\|reconf\|gen\|make]\|aclocal\|LIBTOOL' \
  404. $(addsuffix /*.mk,$(MXE_PLUGIN_DIRS)))))))
  405. CMAKE_PKGS := $(filter-out $(MXE_CONF_PKGS) cmake-conf cmake, \
  406. $(sort $(basename $(notdir \
  407. $(shell grep -l '(TARGET)-cmake' \
  408. $(addsuffix /*.mk,$(MXE_PLUGIN_DIRS)))))))
  409. # all other packages should list their deps explicitly, if tools become
  410. # universally used, we can add them to the toolchain deps (e.g. pkgconf)
  411. # or add new implicit `${TOOL}_PKGS` rules
  412. # $(PKG) and $(TARGET) are in scope from the calling loop so reference
  413. # variables by name instead of position
  414. # explicit normal package deps
  415. PKG_DEPS = \
  416. $(foreach DEP,$(value $(call LOOKUP_PKG_RULE,$(PKG),DEPS,$(TARGET))), \
  417. $(if $(filter $(DEP),$(PKGS)), \
  418. $(if $(or $(value $(call LOOKUP_PKG_RULE,$(DEP),BUILD,$(TARGET))), \
  419. $(filter $($(DEP)_TYPE),$(BUILD_PKG_TYPES))), \
  420. $(TARGET)/installed/$(DEP)) \
  421. $(else), \
  422. $(if $(or $(value $(call LOOKUP_PKG_RULE,$($(DEP)_PKG),BUILD,$($(DEP)_TGT))), \
  423. $(filter $($($(DEP)_PKG)_TYPE),$(BUILD_PKG_TYPES))), \
  424. $($(DEP)_TGT)/installed/$($(DEP)_PKG))))
  425. # order-only package deps unlikely to need target lookup
  426. PKG_OO_DEPS = \
  427. $(foreach DEP,$($(PKG)_OO_DEPS), \
  428. $(if $(filter $(DEP),$(PKGS)), \
  429. $(if $(or $(value $(call LOOKUP_PKG_RULE,$(DEP),BUILD,$(TARGET))), \
  430. $(filter $($(DEP)_TYPE),$(BUILD_PKG_TYPES))), \
  431. $(TARGET)/installed/$(DEP)) \
  432. $(else), \
  433. $(if $(or $(value $(call LOOKUP_PKG_RULE,$($(DEP)_PKG),BUILD,$($(DEP)_TGT))), \
  434. $(filter $($($(DEP)_PKG)_TYPE),$(BUILD_PKG_TYPES))), \
  435. $($(DEP)_TGT)/installed/$($(DEP)_PKG))))
  436. # all deps for download rules (includes source-only pkgs)
  437. PKG_ALL_DEPS = \
  438. $(foreach DEP,$($(PKG)_OO_DEPS) $(value $(call LOOKUP_PKG_RULE,$(PKG),DEPS,$(TARGET))), \
  439. $(if $(filter $(DEP),$(PKGS)), \
  440. $(TARGET)~$(DEP), \
  441. $(DEP)))
  442. # include files from MXE_PLUGIN_DIRS, set base filenames and `all-<plugin>` target
  443. PLUGIN_FILES := $(realpath $(wildcard $(addsuffix /*.mk,$(MXE_PLUGIN_DIRS))))
  444. PKGS := $(sort $(basename $(notdir $(PLUGIN_FILES))))
  445. $(foreach FILE,$(PLUGIN_FILES),\
  446. $(eval $(basename $(notdir $(FILE)))_MAKEFILE ?= $(FILE)) \
  447. $(eval $(basename $(notdir $(FILE)))_TEST_FILE ?= $(filter-out %.cmake,$(wildcard $(basename $(FILE))-test.*))) \
  448. $(eval all-$(lastword $(call split,/,$(dir $(FILE)))): $(basename $(notdir $(FILE)))))
  449. include $(PLUGIN_FILES)
  450. # create target sets for PKG_TARGET_RULE loop to avoid creating empty rules
  451. # and having to explicitly disable $(BUILD) for most packages
  452. # add autotools, cmake, mxe-conf implicit order-only deps
  453. CROSS_TARGETS := $(filter-out $(BUILD),$(MXE_TARGETS))
  454. $(foreach PKG,$(PKGS), \
  455. $(if $(filter $(PKG),$(filter-out $(autotools_DEPS),$(AUTOTOOLS_PKGS))),\
  456. $(eval $(PKG)_OO_DEPS += $(BUILD)~autotools)) \
  457. $(if $(filter $(PKG),$(CMAKE_PKGS)),$(eval $(PKG)_OO_DEPS += cmake-conf)) \
  458. $(if $(filter $(PKG),$(MXE_CONF_PKGS)),,$(eval $(PKG)_OO_DEPS += mxe-conf)) \
  459. $(if $(filter %$(PKG),$(MXE_CONF_PKGS) $(BOOTSTRAP_PKGS)),,$(eval $(PKG)_OO_DEPS += $(BOOTSTRAP_PKGS))) \
  460. $(eval $(PKG)_TARGETS := $(sort $($(PKG)_TARGETS))) \
  461. $(if $($(PKG)_TARGETS),,$(eval $(PKG)_TARGETS := $(CROSS_TARGETS))) \
  462. $(foreach TARGET,$(filter $($(PKG)_TARGETS),$(CROSS_TARGETS) $(BUILD)), \
  463. $(eval $(TARGET)~$(PKG)_PKG := $(PKG)) \
  464. $(eval $(TARGET)~$(PKG)_TGT := $(TARGET)) \
  465. $(eval $(TARGET)_PKGS += $(PKG))))
  466. # always add $(BUILD) to our targets
  467. override MXE_TARGETS := $(CROSS_TARGETS) $(BUILD)
  468. # cache some target string manipulation functions with normal make variables
  469. CHOP_TARGETS = \
  470. $(if $(1),\
  471. $(eval CHOPPED := $(call merge,.,$(call chop,$(call split,.,$(1)))))\
  472. $(eval $(1)_CHOPPED := $(CHOPPED))\
  473. $(call CHOP_TARGETS,$(CHOPPED)))
  474. $(foreach TARGET,$(MXE_TARGETS),\
  475. $(call CHOP_TARGETS,$(TARGET))\
  476. $(eval $(TARGET)_UC_LIB_TYPE := $(if $(findstring shared,$(TARGET)),SHARED,STATIC)))
  477. # finds a package rule defintion
  478. RULE_TYPES := BUILD DEPS FILE MESSAGE URL
  479. # by truncating the target elements then looking for STAIC|SHARED rules:
  480. #
  481. # foo_BUILD_i686-w64-mingw32.static.win32.dw2
  482. # foo_BUILD_i686-w64-mingw32.static.win32
  483. # foo_BUILD_i686-w64-mingw32.static
  484. # foo_BUILD_i686-w64-mingw32
  485. # foo_BUILD_SHARED
  486. # foo_BUILD
  487. # return the pre-populated rule if defined
  488. LOOKUP_PKG_RULE = $(or $(LOOKUP_PKG_RULE_$(1)_$(2)_$(3)),$(1)_$(2))
  489. # $(call _LOOKUP_PKG_RULE, package, rule type, target [, lib type])
  490. # returns variable name for use with $(value). PKG_RULE below will
  491. # populate LOOKUP_PKG_RULE_* variables for rules that require lookups
  492. _LOOKUP_PKG_RULE = $(strip \
  493. $(if $(findstring undefined, $(flavor $(PKG)_$(RULE)_$(3))),\
  494. $(if $(3),\
  495. $(call _LOOKUP_PKG_RULE,$(PKG),$(RULE),$($(3)_CHOPPED),$(or $(4),$($(3)_UC_LIB_TYPE)))\
  496. $(else),\
  497. $(if $(4),\
  498. $(call _LOOKUP_PKG_RULE,$(PKG),$(RULE),$(4))\
  499. $(else),\
  500. $(PKG)_$(RULE)))\
  501. $(else),\
  502. $(PKG)_$(RULE)_$(3)))
  503. # set column widths for build status messages
  504. PKG_COL_WIDTH := $(call plus,2,$(call LIST_NMAX, $(sort $(call map, strlen, $(PKGS)))))
  505. MAX_TARGET_WIDTH := $(call LIST_NMAX, $(sort $(call map, strlen, $(MXE_TARGETS))))
  506. TARGET_COL_WIDTH := $(call subtract,100,$(call plus,$(PKG_COL_WIDTH),$(MAX_TARGET_WIDTH)))
  507. PRINTF_FMT := printf '%-$(PRINTF_COL_1_WIDTH)s %-$(PKG_COL_WIDTH)s %-$(TARGET_COL_WIDTH)s %-15s %s\n'
  508. RTRIM := $(SED) 's, \+$$$$,,'
  509. WRAP_MESSAGE = $(\n)$(\n)$(call repeat,-,60)$(\n)$(1)$(and $(2),$(\n)$(\n)$(2))$(\n)$(call repeat,-,60)$(\n)
  510. define TARGET_RULE
  511. $(if $(findstring i686-pc-mingw32,$(1)),\
  512. $(error $(call WRAP_MESSAGE,\
  513. Obsolete target specified: "$(1)",\
  514. Please use i686-w64-mingw32.[$(subst $(space),|,$(MXE_LIB_TYPES))]$(\n)\
  515. i686-pc-mingw32 removed 2014-10-14 (https://github.com/mxe/mxe/pull/529)\
  516. )))\
  517. $(if $(filter $(addsuffix %,$(MXE_TARGET_LIST) $(BUILD) $(MXE_TRIPLETS)),$(1)),,\
  518. $(error $(call WRAP_MESSAGE,\
  519. Invalid target specified: "$(1)",\
  520. Please use:$(\n)\
  521. $(subst $(space),$(\n) ,$(MXE_TARGET_LIST))\
  522. )))\
  523. $(if $(findstring 1,$(words $(subst ., ,$(filter-out $(BUILD),$(1))))),\
  524. $(warning $(call WRAP_MESSAGE,\
  525. Warning: Deprecated target specified "$(1)",\
  526. Please use $(1).[$(subst $(space),|,$(MXE_LIB_TYPES))]$(\n) \
  527. )))
  528. endef
  529. $(foreach TARGET,$(MXE_TARGETS),$(call TARGET_RULE,$(TARGET)))
  530. define PKG_RULE
  531. # configure GitHub metadata if GH_CONF is set
  532. $(if $($(PKG)_GH_CONF),$(eval $(MXE_SETUP_GITHUB)))
  533. $(eval $(PKG)_PATCHES := $(PKG_PATCHES))
  534. .PHONY: download-only-$(1)
  535. # Packages can share a source archive to build different sets of features
  536. # or dependencies (see bfd/binutils openscenegraph/openthreads qwt/qwt_qt4).
  537. # Use a double-colon rule to allow multiple definitions:
  538. # https://www.gnu.org/software/make/manual/html_node/Double_002dColon.html
  539. # N.B. the `::` rule will use values from first lexical definition e.g.:
  540. # $ make download-only-binutils
  541. # [download] bfd
  542. .PHONY: download-only-$($(1)_FILE)
  543. download-only-$(1): download-only-$($(1)_FILE)
  544. download-only-$($(1)_FILE)::
  545. $(and $($(1)_URL),
  546. @$$(if $$(REMOVE_DOWNLOAD),rm -f '$(PKG_DIR)/$($(1)_FILE)')
  547. @if ! $(call CHECK_PKG_ARCHIVE,$(1)); then \
  548. $(PRINTF_FMT) '[download]' '$($(1)_FILE)' | $(RTRIM); \
  549. [ -d '$(LOG_DIR)/$(TIMESTAMP)' ] || mkdir -p '$(LOG_DIR)/$(TIMESTAMP)'; \
  550. ($(call DOWNLOAD_PKG_ARCHIVE,$(1))) &> '$(LOG_DIR)/$(TIMESTAMP)/$(1)-download'; \
  551. grep 'MXE Warning' '$(LOG_DIR)/$(TIMESTAMP)/$(1)-download'; \
  552. ln -sf '$(TIMESTAMP)/$(1)-download' '$(LOG_DIR)/$(1)-download'; \
  553. if ! $(call CHECK_PKG_ARCHIVE,$(1)); then \
  554. echo; \
  555. echo 'Download failed or wrong checksum of package $(1)!'; \
  556. echo '------------------------------------------------------------'; \
  557. $(if $(findstring undefined, $(origin MXE_VERBOSE)),\
  558. tail -n 10 '$(LOG_DIR)/$(1)-download' | $(SED) -n '/./p';, \
  559. $(SED) -n '/./p' '$(LOG_DIR)/$(1)-download';) \
  560. echo '------------------------------------------------------------'; \
  561. echo '[log] $(LOG_DIR)/$(1)-download'; \
  562. echo; \
  563. exit 1; \
  564. fi; \
  565. fi)
  566. .PHONY: prepare-pkg-source-$(1)
  567. prepare-pkg-source-$(1): download-only-$(1)
  568. rm -rf '$(2)'
  569. mkdir -p '$(2)'
  570. $$(call PREPARE_PKG_SOURCE,$(1),$(2))
  571. # populate LOOKUP_PKG_RULE_ variables where there are multiple defined
  572. $(foreach RULE,$(RULE_TYPES),\
  573. $(if $(filter-out %_URL_2,$(filter-out $(PKG)_$(RULE),$(filter $(PKG)_$(RULE)%,$(.VARIABLES)))),\
  574. $(foreach TARGET,$(MXE_TARGETS),\
  575. $(eval LOOKUP_PKG_RULE_$(PKG)_$(RULE)_$(TARGET) := $(call _LOOKUP_PKG_RULE,$(PKG),$(RULE),$(TARGET))))))
  576. endef
  577. $(foreach PKG,$(PKGS),$(eval $(call PKG_RULE,$(PKG),$(call TMP_DIR,$(PKG)))))
  578. # disable networking during build-only rules for reproducibility
  579. ifeq ($(findstring darwin,$(BUILD)),)
  580. NONET_LIB := $(PREFIX)/$(BUILD)/lib/nonetwork.so
  581. PRELOAD := LD_PRELOAD='$(NONET_LIB)'
  582. else
  583. NONET_LIB := $(PREFIX)/$(BUILD)/lib/nonetwork.dylib
  584. PRELOAD := DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES='$(NONET_LIB)'
  585. NONET_CFLAGS := -arch x86_64
  586. endif
  587. $(NONET_LIB): $(TOP_DIR)/tools/nonetwork.c | $(PREFIX)/$(BUILD)/lib/.gitkeep
  588. @$(PRINTF_FMT) '[nonet lib]' '$@'
  589. +@$(BUILD_CC) -shared -fPIC $(NONET_CFLAGS) -o $@ $<
  590. .PHONY: nonet-lib
  591. nonet-lib: $(NONET_LIB)
  592. .PHONY: shell
  593. shell: $(NONET_LIB)
  594. $(PRELOAD) $(SHELL)
  595. define PKG_TARGET_RULE
  596. .PHONY: download-$(1)
  597. download-$(1): download-$(3)~$(1) download-only-$(1)
  598. .PHONY: download-$(3)~$(1)
  599. download-$(3)~$(1): download-only-$(1) \
  600. $(addprefix download-,$(PKG_ALL_DEPS))
  601. .PHONY: $(1) $(1)~$(3)
  602. # requested pkgs should not build their native version unless
  603. # explicitly set in DEPS or they only have a single target
  604. $(if $(filter-out $(BUILD),$(3))$(call not,$(word 2,$($(1)_TARGETS))),$(1)) \
  605. $(1)~$(3): $(PREFIX)/$(3)/installed/$(1)
  606. $(PREFIX)/$(3)/installed/$(1): $(PKG_MAKEFILES) \
  607. $($(PKG)_PATCHES) \
  608. $(PKG_TESTFILES) \
  609. $($(1)_FILE_DEPS) \
  610. $(addprefix $(PREFIX)/,$(PKG_DEPS)) \
  611. | $(if $(DONT_CHECK_REQUIREMENTS),,check-requirements) \
  612. $(if $(value $(call LOOKUP_PKG_RULE,$(1),URL,$(3))),download-only-$(1)) \
  613. $(addprefix $(PREFIX)/,$(PKG_OO_DEPS)) \
  614. $(addprefix download-,$(PKG_ALL_DEPS)) \
  615. $(NONET_LIB) \
  616. $(PREFIX)/$(3)/installed/.gitkeep \
  617. print-git-oneline
  618. $(if $(value $(call LOOKUP_PKG_RULE,$(1),MESSAGE,$(3))),
  619. @$(PRINTF_FMT) '[message]' '$(1)' '$(3) $($(call LOOKUP_PKG_RULE,$(1),MESSAGE,$(3)))' \
  620. | $(RTRIM)
  621. )
  622. $(if $(value $(call LOOKUP_PKG_RULE,$(1),BUILD,$(3))),
  623. $(if $(BUILD_DRY_RUN)$(MXE_BUILD_DRY_RUN), \
  624. @$(PRINTF_FMT) '[dry-run]' '$(1)' '$(3)' | $(RTRIM)
  625. @[ -d '$(PREFIX)/$(3)/lib' ] || mkdir -p '$(PREFIX)/$(3)/lib'
  626. @echo $(1)~$(3) > '$(PREFIX)/$(3)/lib/$(1).dry-run'
  627. @touch '$(PREFIX)/$(3)/installed/$(1)'
  628. $(else),
  629. @$(PRINTF_FMT) '[build]' '$(1)' '$(3)' | $(RTRIM)
  630. @[ -d '$(LOG_DIR)/$(TIMESTAMP)' ] || mkdir -p '$(LOG_DIR)/$(TIMESTAMP)'
  631. @touch '$(LOG_DIR)/$(TIMESTAMP)/$(1)_$(3)'
  632. @ln -sf '$(TIMESTAMP)/$(1)_$(3)' '$(LOG_DIR)/$(1)_$(3)'
  633. @if ! (time $(PRELOAD) WINEPREFIX='$(2)/readonly' \
  634. $(MAKE) -f '$(MAKEFILE)' \
  635. 'build-only-$(1)_$(3)' \
  636. WGET=false \
  637. ) &> '$(LOG_DIR)/$(TIMESTAMP)/$(1)_$(3)'; then \
  638. echo; \
  639. echo 'Failed to build package $(1) for target $(3)!'; \
  640. echo '------------------------------------------------------------'; \
  641. $(if $(findstring undefined, $(origin MXE_VERBOSE)),\
  642. tail -n 10 '$(LOG_DIR)/$(1)_$(3)' | $(SED) -n '/./p';, \
  643. $(SED) -n '/./p' '$(LOG_DIR)/$(1)_$(3)';) \
  644. echo '------------------------------------------------------------'; \
  645. echo '[log] $(LOG_DIR)/$(1)_$(3)'; \
  646. echo; \
  647. exit 1; \
  648. fi
  649. @$(PRINTF_FMT) '[done]' '$(1)' '$(3)' "`grep -a '^du:.*KiB$$\' '$(LOG_DIR)/$(TIMESTAMP)/$(1)_$(3)' | cut -d ':' -f2 | tail -1`" \
  650. "`grep -a '^real.*m.*s$$\' '$(LOG_DIR)/$(TIMESTAMP)/$(1)_$(3)' | tr '\t' ' ' | cut -d ' ' -f2 | tail -1`"
  651. )
  652. $(else),
  653. @$(PRINTF_FMT) '[$(or $($(PKG)_TYPE),disabled)]' '$(1)' '$(3)' | $(RTRIM)
  654. @touch '$(PREFIX)/$(3)/installed/$(1)'
  655. )
  656. .PHONY: build-only-$(1)_$(3)
  657. # target-specific variables provide an extra level of scoping so that named
  658. # variables can be used in package build rules:
  659. # https://www.gnu.org/software/make/manual/html_node/Target_002dspecific.html
  660. build-only-$(1)_$(3): PKG = $(1)
  661. build-only-$(1)_$(3): TARGET = $(3)
  662. build-only-$(1)_$(3): BUILD_$(if $(findstring shared,$(3)),SHARED,STATIC) = TRUE
  663. build-only-$(1)_$(3): BUILD_$(if $(call seq,$(TARGET),$(BUILD)),NATIVE,CROSS) = TRUE
  664. build-only-$(1)_$(3): $(if $(findstring win32,$(TARGET)),WIN32,POSIX)_THREADS = TRUE
  665. build-only-$(1)_$(3): LIB_SUFFIX = $(if $(findstring shared,$(3)),dll,a)
  666. build-only-$(1)_$(3): BITS = $(if $(findstring x86_64,$(3)),64,32)
  667. build-only-$(1)_$(3): PROCESSOR = $(firstword $(call split,-,$(3)))
  668. build-only-$(1)_$(3): BUILD_TYPE = $(if $(findstring debug,$(3) $($(1)_CONFIGURE_OPTS)),debug,release)
  669. build-only-$(1)_$(3): BUILD_TYPE_SUFFIX = $(if $(findstring debug,$(3) $($(1)_CONFIGURE_OPTS)),d)
  670. build-only-$(1)_$(3): INSTALL_STRIP_TOOLCHAIN = install$(if $(STRIP_TOOLCHAIN),-strip)
  671. build-only-$(1)_$(3): INSTALL_STRIP_LIB = install$(if $(STRIP_LIB),-strip)
  672. build-only-$(1)_$(3): SOURCE_DIR = $(or $(realpath $($(1)_SOURCE_TREE)),$(2)/$($(1)_SUBDIR))
  673. build-only-$(1)_$(3): BUILD_DIR = $(2)/$(if $($(1)_SOURCE_TREE),local,$($(1)_SUBDIR)).build_
  674. build-only-$(1)_$(3): TEST_FILE = $($(1)_TEST_FILE)
  675. build-only-$(1)_$(3): CMAKE_RUNRESULT_FILE = $(PREFIX)/share/cmake/modules/TryRunResults.cmake
  676. build-only-$(1)_$(3): CMAKE_TOOLCHAIN_FILE = $(PREFIX)/$(3)/share/cmake/mxe-conf.cmake
  677. build-only-$(1)_$(3): CMAKE_TOOLCHAIN_DIR = $(PREFIX)/$(3)/share/cmake/mxe-conf.d
  678. build-only-$(1)_$(3): CMAKE_STATIC_BOOL = $(if $(findstring shared,$(3)),OFF,ON)
  679. build-only-$(1)_$(3): CMAKE_SHARED_BOOL = $(if $(findstring shared,$(3)),ON,OFF)
  680. build-only-$(1)_$(3):
  681. $(if $(value $(call LOOKUP_PKG_RULE,$(1),BUILD,$(3))),
  682. uname -a
  683. - git log --pretty=tformat:"%H - %s [%ar] [%d]" -1
  684. lsb_release -a 2>/dev/null || sw_vers 2>/dev/null || true
  685. autoconf --version 2>/dev/null | head -1
  686. automake --version 2>/dev/null | head -1
  687. $(BUILD_CC) --version
  688. $(BUILD_CXX) --version
  689. python --version
  690. perl --version 2>&1 | head -3
  691. rm -rf '$(2)'
  692. mkdir -p '$(2)'
  693. mkdir -p '$$(SOURCE_DIR)'
  694. mkdir -p '$$(BUILD_DIR)'
  695. # disable wine with readonly directory
  696. # see https://github.com/mxe/mxe/issues/841
  697. mkdir -p '$(2)/readonly'
  698. chmod 0555 '$(2)/readonly'
  699. $$(if $(and $(value $(call LOOKUP_PKG_RULE,$(1),FILE,$(3))),\
  700. $(call not,$(filter $(SCRIPT_PKG_TYPES),$($(PKG)_TYPE)))),\
  701. $$(call PREPARE_PKG_SOURCE,$(1),$(2)))
  702. $$(call $(call LOOKUP_PKG_RULE,$(1),BUILD,$(3)),$(2)/$($(1)_SUBDIR))
  703. @echo
  704. @find '$(2)' -name 'config.log' -print -exec cat {} \;
  705. @echo
  706. @echo 'settings.mk'
  707. @cat '$(TOP_DIR)/settings.mk'
  708. $(if $(STRIP_EXE),-$(TARGET)-strip '$(PREFIX)/$(TARGET)/bin/test-$(PKG).exe')
  709. (du -k -d 0 '$(2)' 2>/dev/null || du -k --max-depth 0 '$(2)') | $(SED) -n 's/^\(\S*\).*/du: \1 KiB/p'
  710. rm -rfv '$(2)'
  711. )
  712. touch '$(PREFIX)/$(3)/installed/$(1)'
  713. endef
  714. $(foreach TARGET,$(MXE_TARGETS), \
  715. $(foreach PKG,$($(TARGET)_PKGS), \
  716. $(eval $(call PKG_TARGET_RULE,$(PKG),$(call TMP_DIR,$(PKG)-$(TARGET)),$(TARGET)))))
  717. # convenience set-like functions for unique lists
  718. SET_APPEND = \
  719. $(eval $(1) := $(sort $($(1)) $(2)))
  720. SET_CLEAR = \
  721. $(eval $(1) := )
  722. # WALK functions accept a list of pkgs and/or wildcards
  723. # use PKG_ALL_DEPS and strip target prefixes to get
  724. # global package level deps
  725. WALK_UPSTREAM = \
  726. $(strip \
  727. $(foreach PKG,$(filter $(1),$(PKGS)),\
  728. $(foreach TARGET,$($(PKG)_TARGETS), \
  729. $(foreach DEP,$(sort $(subst $(BUILD)~,,$(subst $(TARGET)~,,$(PKG_ALL_DEPS)))),\
  730. $(if $(filter-out $(PKGS_VISITED),$(DEP)),\
  731. $(call SET_APPEND,PKGS_VISITED,$(DEP))\
  732. $(call WALK_UPSTREAM,$(DEP))\
  733. $(DEP))))))
  734. # not really walking downstream - that seems to be quadratic, so take
  735. # a linear approach and filter the fully expanded upstream for each pkg
  736. WALK_DOWNSTREAM = \
  737. $(strip \
  738. $(foreach PKG,$(PKGS),\
  739. $(call SET_CLEAR,PKGS_VISITED)\
  740. $(eval ALL_$(PKG)_DEPS := $(call WALK_UPSTREAM,$(PKG))))\
  741. $(foreach PKG,$(PKGS),\
  742. $(if $(filter $(1),$(ALL_$(PKG)_DEPS)),$(PKG))))
  743. # list of direct downstream deps
  744. DIRECT_DOWNSTREAM = \
  745. $(strip \
  746. $(foreach PKG,$(PKGS),\
  747. $(if $(filter $(1),$($(PKG)_DEPS)),$(PKG))))
  748. # EXCLUDE_PKGS can be a list of pkgs and/or wildcards
  749. RECURSIVELY_EXCLUDED_PKGS = \
  750. $(sort \
  751. $(filter $(EXCLUDE_PKGS),$(PKGS))\
  752. $(call SET_CLEAR,PKGS_VISITED)\
  753. $(call WALK_DOWNSTREAM,$(EXCLUDE_PKGS)))
  754. # INCLUDE_PKGS can be a list of pkgs and/or wildcards
  755. # only used by build-pkg
  756. INCLUDE_PKGS := $(MXE_BUILD_PKG_PKGS)
  757. RECURSIVELY_INCLUDED_PKGS = \
  758. $(sort \
  759. $(filter $(INCLUDE_PKGS),$(PKGS))\
  760. $(call SET_CLEAR,PKGS_VISITED)\
  761. $(call WALK_UPSTREAM,$(INCLUDE_PKGS)))
  762. REQUIRED_PKGS = \
  763. $(filter-out $(and $(EXCLUDE_PKGS),$(RECURSIVELY_EXCLUDED_PKGS)),\
  764. $(or $(and $(INCLUDE_PKGS),$(strip $(RECURSIVELY_INCLUDED_PKGS))),$(PKGS)))
  765. .PHONY: all-filtered
  766. all-filtered: $(REQUIRED_PKGS)
  767. .PHONY: download
  768. download: $(addprefix download-,$(REQUIRED_PKGS))
  769. # print a list of upstream dependencies and downstream dependents
  770. show-deps-%:
  771. $(if $(call set_is_member,$*,$(PKGS)),\
  772. $(call SET_CLEAR,PKGS_VISITED)\
  773. $(info $* upstream dependencies:$(newline)\
  774. $(call WALK_UPSTREAM,$*)\
  775. $(newline)$(newline)$* direct downstream dependents:$(newline)\
  776. $(call DIRECT_DOWNSTREAM,$*)\
  777. $(newline)$(newline)$* recursive downstream dependents:$(newline)\
  778. $(call WALK_DOWNSTREAM,$*))\
  779. @echo,\
  780. $(error Package $* not found))
  781. # show upstream dependencies and downstream dependents separately
  782. # suitable for usage in shell with: `make show-downstream-deps-foo`
  783. # @echo -n suppresses the "Nothing to be done" without an eol
  784. show-downstream-deps-%:
  785. $(if $(call set_is_member,$*,$(PKGS)),\
  786. $(call SET_CLEAR,PKGS_VISITED)\
  787. $(info $(call WALK_DOWNSTREAM,$*))\
  788. @echo -n,\
  789. $(error Package $* not found))
  790. show-direct-downstream-deps-%:
  791. $(if $(call set_is_member,$*,$(PKGS)),\
  792. $(info $(call DIRECT_DOWNSTREAM,$*))\
  793. @echo -n,\
  794. $(error Package $* not found))
  795. show-upstream-deps-%:
  796. $(if $(call set_is_member,$*,$(PKGS)),\
  797. $(call SET_CLEAR,PKGS_VISITED)\
  798. $(info $(call WALK_UPSTREAM,$*))\
  799. @echo -n,\
  800. $(error Package $* not found))
  801. # print first level pkg deps for use in build-pkg.lua
  802. .PHONY: print-deps-for-build-pkg
  803. print-deps-for-build-pkg:
  804. $(foreach TARGET,$(sort $(MXE_TARGETS)), \
  805. $(foreach PKG,$(filter $(REQUIRED_PKGS),$(sort $($(TARGET)_PKGS))), \
  806. $(if $(or $(value $(call LOOKUP_PKG_RULE,$(PKG),BUILD,$(TARGET))), \
  807. $(filter $($(PKG)_TYPE),$(BUILD_PKG_TYPES))), \
  808. $(info $(strip for-build-pkg $(TARGET)~$(PKG) \
  809. $(subst $(space),-,$($(PKG)_VERSION)-$(OS_SHORT_NAME)) \
  810. $(subst /installed/,~,$(PKG_DEPS) $(PKG_OO_DEPS)))))))
  811. @echo -n
  812. BUILD_PKG_TMP_FILES := *-*.list mxe-*.tar.xz mxe-*.deb* wheezy jessie
  813. .PHONY: clean
  814. clean:
  815. rm -rf $(call TMP_DIR,*) $(PREFIX) \
  816. $(addprefix $(TOP_DIR)/, $(BUILD_PKG_TMP_FILES))
  817. @echo
  818. @echo 'review ccache size with:'
  819. @echo '$(MXE_CCACHE_DIR)/bin/ccache -s'
  820. .PHONY: clean-pkg
  821. clean-pkg:
  822. rm -f $(patsubst %,'%', \
  823. $(filter-out \
  824. $(foreach PKG,$(PKGS),$(PKG_DIR)/$($(PKG)_FILE) $(PKG_DIR)/$($(PKG)_FILE)_$($(PKG)_CHECKSUM)), \
  825. $(wildcard $(PKG_DIR)/*)))
  826. .PHONY: clean-junk
  827. clean-junk: clean-pkg
  828. rm -rf $(LOG_DIR) $(call TMP_DIR,*)
  829. .PHONY: cleanup-style
  830. define CLEANUP_STYLE
  831. @$(SED) ' \
  832. s/\r//g; \
  833. s/[ \t]\+$$//; \
  834. s,^#!/bin/bash$$,#!/usr/bin/env bash,; \
  835. $(if $(filter %Makefile,$(1)),,\
  836. s/\t/ /g; \
  837. ) \
  838. ' < $(1) > $(TOP_DIR)/tmp-cleanup-style
  839. @diff -u $(1) $(TOP_DIR)/tmp-cleanup-style >/dev/null \
  840. || { echo '[cleanup] $(1)'; \
  841. cp $(TOP_DIR)/tmp-cleanup-style $(1); }
  842. @rm -f $(TOP_DIR)/tmp-cleanup-style
  843. endef
  844. cleanup-style:
  845. $(foreach FILE,$(wildcard $(addprefix $(TOP_DIR)/,Makefile docs/index.html docs/CNAME src/*.mk src/*test.* tools/*)),$(call CLEANUP_STYLE,$(FILE)))
  846. .PHONY: cleanup-deps-style
  847. cleanup-deps-style:
  848. @grep '(PKG)_DEPS.*\\' $(foreach 1,$(PKGS),$(PKG_MAKEFILES)) > $(TOP_DIR)/tmp-$@-pre
  849. @$(foreach PKG,$(PKGS), \
  850. $(if $(call lne,$(sort $(filter-out $(CROSS_COMPILER),$($(PKG)_DEPS))),$(filter-out $(CROSS_COMPILER),$($(PKG)_DEPS))), \
  851. $(info [cleanup] $(PKG)) \
  852. $(SED) -i 's/^\([^ ]*_DEPS *:=\)[^$$]*$$/\1 '"$(strip $(filter $(CROSS_COMPILER),$($(PKG)_DEPS)) $(sort $(filter-out $(CROSS_COMPILER),$($(PKG)_DEPS))))"'/' '$(call PKG_MAKEFILES,$(PKG))'; \
  853. ))
  854. @grep '(PKG)_DEPS.*\\' $(foreach 1,$(PKGS),$(PKG_MAKEFILES)) > $(TOP_DIR)/tmp-$@-post
  855. @diff -u $(TOP_DIR)/tmp-$@-pre $(TOP_DIR)/tmp-$@-post >/dev/null \
  856. || echo '*** Multi-line deps are mangled ***' && comm -3 tmp-$@-pre tmp-$@-post
  857. @rm -f $(TOP_DIR)/tmp-$@-*
  858. .PHONY: docs/build-matrix.html
  859. docs/build-matrix.html: $(foreach 1,$(PKGS),$(PKG_MAKEFILES))
  860. @echo '<!DOCTYPE html>' > $@
  861. @echo '<html>' >> $@
  862. @echo '<head>' >> $@
  863. @echo '<meta http-equiv="content-type" content="text/html; charset=utf-8">' >> $@
  864. @echo '<title>MXE Build Matrix</title>' >> $@
  865. @echo '<link rel="stylesheet" href="assets/common.css">' >> $@
  866. @echo '<link rel="stylesheet" href="assets/build-matrix.css">' >> $@
  867. @echo '</head>' >> $@
  868. @echo '<body>' >> $@
  869. @echo '<h2>MXE Build Matrix</h2>' >> $@
  870. @echo '<p>' >> $@
  871. @echo 'This is a table of all supported package/target' >> $@
  872. @echo 'matrix. Being supported means that this specific' >> $@
  873. @echo 'combination is working to the best of our knowledge,' >> $@
  874. @echo 'but does not mean that it is tested daily.' >> $@
  875. @echo '</p>' >> $@
  876. @echo '<p>' >> $@
  877. @echo 'If you found that some package is not working properly,'>> $@
  878. @echo 'please file a ticket on GitHub. If you figured out a' >> $@
  879. @echo 'way to make the package work for unsupported targets,' >> $@
  880. @echo 'feel free to submit a pull request.' >> $@
  881. @echo '</p>' >> $@
  882. @echo '<table class="fullscreen">' >> $@
  883. @echo '<thead>' >> $@
  884. @echo '<tr>' >> $@
  885. @echo '<th rowspan="2">Package</th>' >> $@
  886. @echo '<th rowspan="2">Version</th>' >> $@
  887. @$(foreach TRIPLET,$(MXE_TRIPLETS), \
  888. echo '<th colspan="$(words $(MXE_LIB_TYPES))">$(TRIPLET)</th>' >> $@;)
  889. @echo '<th rowspan="2">Native</th>' >> $@
  890. @echo '</tr>' >> $@
  891. @echo '<tr>' >> $@
  892. @$(foreach TRIPLET,$(MXE_TRIPLETS), \
  893. $(foreach LIB, $(MXE_LIB_TYPES), \
  894. echo '<th>$(LIB)</th>' >> $@;))
  895. @echo '</tr>' >> $@
  896. @echo '</thead>' >> $@
  897. @echo '<tbody>' >> $@
  898. # It is important to remember that the PKGCOUNT variables
  899. # are expressed in unary terms. So, after 5 virtual packages,
  900. # the content of $(VIRTUAL_PKGCOUNT) would be "x x x x x" and not "5".
  901. # Therefore, when using the PKGCOUNT, you have to use
  902. # $(words $(VIRTUAL_PKGCOUNT))
  903. # The same operations are included in GMSL "Integer Arithmetic Functions."
  904. # I chose not to use most of them because their names are too long.
  905. # $(eval $(VIRTUAL_PKGCOUNT += x))
  906. # vs
  907. # $(eval $(VIRTUAL_PKGCOUNT := $(call int_inc,$(VIRTUAL_PKGCOUNT))))
  908. @$(foreach PKG,$(PKGS), \
  909. $(eval $(PKG)_VIRTUAL := $(true)) \
  910. $(eval $(PKG)_BUILD_ONLY := $(true)) \
  911. echo -e '<tr>\n \
  912. <th class="row" \
  913. title="$($(PKG)_MESSAGE)"> \
  914. $(PKG) \
  915. $(if $($(PKG)_TYPE), [$($(PKG)_TYPE)-pkg]) \
  916. $(if $($(PKG)_MESSAGE), **)\
  917. </th>\n \
  918. <td>$(call substr,$($(PKG)_VERSION),1,12) \
  919. $(if $(call gt,$(call strlen,$($(PKG)_VERSION)),12),&hellip;)</td>\n\
  920. $(foreach TARGET,$(MXE_TARGET_LIST), \
  921. $(if $(filter $(VIRTUAL_PKG_TYPES),$($(PKG)_TYPE)), \
  922. $(if $(filter $(TARGET),$($(PKG)_TARGETS)), \
  923. <td class="neutral">&bull;</td>, \
  924. <td></td>), \
  925. $(if $(filter $(TARGET),$($(PKG)_TARGETS)), \
  926. $(if $(value $(call LOOKUP_PKG_RULE,$(PKG),BUILD,$(TARGET))), \
  927. $(eval $(TARGET)_PKGCOUNT += x) \
  928. <td class="supported">&#x2713;</td>, \
  929. <td class="unsupported">&#215;</td>),\
  930. <td></td>))\n) \
  931. $(if $(filter $(VIRTUAL_PKG_TYPES),$($(PKG)_TYPE)), \
  932. $(eval VIRTUAL_PKGCOUNT += x) \
  933. $(if $(filter $(BUILD),$($(PKG)_TARGETS)), \
  934. <td class="neutral">&bull;</td>, \
  935. <td></td>), \
  936. $(if $(filter $(BUILD),$($(PKG)_TARGETS)), \
  937. $(if $(value $(call LOOKUP_PKG_RULE,$(PKG),BUILD,$(BUILD))), \
  938. <td class="supported">&#x2713;</td>, \
  939. <td class="unsupported">&#215;</td>), \
  940. <td></td>))\n \
  941. </tr>\n' >> $@ $(newline) \
  942. $(if $(call seq,$(BUILD),$($(PKG)_TARGETS)), \
  943. $(eval BUILD_ONLY_PKGCOUNT += x)))
  944. @echo '<tr>' >> $@
  945. @echo '<th class="row" colspan="2">' >> $@
  946. # TOTAL_PKGCOUNT = PKGS - (VIRTUAL + BUILD_ONLY)
  947. @echo 'Total: $(call subtract, \
  948. $(words $(PKGS)), \
  949. $(words $(VIRTUAL_PKGCOUNT) $(BUILD_ONLY_PKGCOUNT)))'\
  950. >> $@
  951. @echo '<br>(+$(words $(VIRTUAL_PKGCOUNT)) virtual' >> $@
  952. @echo '+$(words $(BUILD_ONLY_PKGCOUNT)) native-only)' >> $@
  953. @echo '</th>' >> $@
  954. @$(foreach TARGET,$(MXE_TARGET_LIST), \
  955. echo '<th>$(words $($(TARGET)_PKGCOUNT))</th>' >> $@;)
  956. @echo '<th>$(words $($(BUILD)_PKGS))</th>' >> $@
  957. @echo '</tr>' >> $@
  958. @echo '</tbody>' >> $@
  959. @echo '</table>' >> $@
  960. @echo '</body>' >> $@
  961. @echo '</html>' >> $@
  962. .PHONY: docs/packages.json
  963. docs/packages.json: $(foreach 1,$(PKGS),$(PKG_MAKEFILES))
  964. @echo '{' > $@
  965. @{$(foreach PKG,$(PKGS), \
  966. echo ' "$(PKG)": \
  967. {"version": "$($(PKG)_VERSION)", \
  968. "website": "$($(PKG)_WEBSITE)", \
  969. "description": "$($(PKG)_DESCR)"},';)} >> $@
  970. @echo ' "": null' >> $@
  971. @echo '}' >> $@
  972. # for other mxe functions
  973. include mxe.patch.mk
  974. include mxe.updates.mk