Makefile raw
1 .NOTPARALLEL :
2 # Disable builtin variables, rules and suffixes.
3 MAKEFLAGS += --no-builtin-rules --no-builtin-variables
4
5 # Pattern rule to print variables, e.g. make print-top_srcdir
6 print-%: FORCE
7 @echo '$*'='$($*)'
8
9 # When invoking a sub-make, keep only the command line variable definitions
10 # matching the pattern in the filter function.
11 #
12 # e.g. invoking:
13 # $ make A=1 C=1 print-MAKEOVERRIDES print-MAKEFLAGS
14 #
15 # with the following in the Makefile:
16 # MAKEOVERRIDES := $(filter A=% B=%,$(MAKEOVERRIDES))
17 #
18 # will print:
19 # MAKEOVERRIDES = A=1
20 # MAKEFLAGS = -- A=1
21 #
22 # this is because as the GNU make manual says:
23 # The command line variable definitions really appear in the variable
24 # MAKEOVERRIDES, and MAKEFLAGS contains a reference to this variable.
25 #
26 # and since the GNU make manual also says:
27 # variables defined on the command line are passed to the sub-make through
28 # MAKEFLAGS
29 #
30 # this means that sub-makes will be invoked as if:
31 # $(MAKE) A=1 blah blah
32 MAKEOVERRIDES := $(filter V=%,$(MAKEOVERRIDES))
33 SOURCES_PATH ?= $(BASEDIR)/sources
34 WORK_PATH = $(BASEDIR)/work
35 BASE_CACHE ?= $(BASEDIR)/built
36 SDK_PATH ?= $(BASEDIR)/SDKs
37 NO_BOOST ?=
38 NO_QT ?=
39 NO_QR ?=
40 NO_WALLET ?=
41 NO_ZMQ ?=
42 NO_USDT ?=
43 # Default NO_IPC value is 1 on Windows
44 NO_IPC ?= $(if $(findstring mingw32,$(HOST)),1,)
45 LTO ?=
46 FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
47
48 C_STANDARD ?= c11
49 CXX_STANDARD ?= c++20
50
51 BUILD = $(shell unset CC && ./config.guess)
52 PATCHES_PATH = $(BASEDIR)/patches
53 BASEDIR = $(CURDIR)
54 HASH_LENGTH:=11
55 DOWNLOAD_CONNECT_TIMEOUT:=30
56 DOWNLOAD_RETRIES:=3
57 HOST_ID_SALT ?= salt
58 BUILD_ID_SALT ?= salt
59
60 ifneq ($(DEBUG),)
61 release_type=debug
62 else
63 release_type=release
64 endif
65
66 base_build_dir=$(WORK_PATH)/build
67 base_staging_dir=$(WORK_PATH)/staging
68 base_download_dir=$(WORK_PATH)/download
69 build:=$(shell ./config.sub $(BUILD))
70
71 host:=$(build)
72 ifneq ($(HOST),)
73 host:=$(HOST)
74 endif
75 HOST ?= $(BUILD)
76 canonical_host:=$(shell ./config.sub $(HOST))
77
78 build_arch =$(firstword $(subst -, ,$(build)))
79 build_vendor=$(word 2,$(subst -, ,$(build)))
80 full_build_os:=$(subst $(build_arch)-$(build_vendor)-,,$(build))
81 build_os:=$(findstring linux,$(full_build_os))
82 build_os+=$(findstring darwin,$(full_build_os))
83 build_os+=$(findstring freebsd,$(full_build_os))
84 build_os+=$(findstring netbsd,$(full_build_os))
85 build_os+=$(findstring openbsd,$(full_build_os))
86 build_os:=$(strip $(build_os))
87 ifeq ($(build_os),)
88 build_os=$(full_build_os)
89 endif
90
91 host_arch=$(firstword $(subst -, ,$(canonical_host)))
92 host_vendor=$(word 2,$(subst -, ,$(canonical_host)))
93 full_host_os:=$(subst $(host_arch)-$(host_vendor)-,,$(canonical_host))
94 host_os:=$(findstring linux,$(full_host_os))
95 host_os+=$(findstring darwin,$(full_host_os))
96 host_os+=$(findstring freebsd,$(full_host_os))
97 host_os+=$(findstring netbsd,$(full_host_os))
98 host_os+=$(findstring openbsd,$(full_host_os))
99 host_os+=$(findstring mingw32,$(full_host_os))
100
101 host_os:=$(strip $(host_os))
102 ifeq ($(host_os),)
103 host_os=$(full_host_os)
104 endif
105
106 $(host_arch)_$(host_os)_prefix=$(BASEDIR)/$(host)
107 $(host_arch)_$(host_os)_host=$(host)
108 host_prefix=$($(host_arch)_$(host_os)_prefix)
109 build_prefix=$(host_prefix)/native
110 build_host=$(build)
111
112 all: install
113
114 include hosts/$(host_os).mk
115 include hosts/default.mk
116 include builders/$(build_os).mk
117 include builders/default.mk
118 include packages/packages.mk
119
120 # Previously, we directly invoked the well-known programs using $(shell ...)
121 # to construct build_id_string. However, that was problematic because:
122 #
123 # 1. When invoking a shell, GNU Make special-cases exit code 127 (command not
124 # found) by not capturing the output but instead passing it through. This is
125 # not done for any other exit code.
126 #
127 # 2. Characters like '#' (from these programs' output) would end up in make
128 # variables like build_id_string, which would be wrongly interpreted by make
129 # when these variables were used.
130 #
131 # Therefore, we should avoid having arbitrary strings in make variables where
132 # possible. The gen_id script used here hashes the output to construct a
133 # "make-safe" id.
134 #
135 # Also note that these lines need to be:
136 #
137 # 1. After including {hosts,builders}/*.mk, since they rely on the tool
138 # variables (e.g. build_CC, host_STRIP, etc.) to be set.
139 #
140 # 2. Before including packages/*.mk (excluding packages/packages.mk), since
141 # they rely on the build_id variables
142 #
143 build_id:=$(shell env CC='$(build_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(build_CXX)' CXX_STANDARD='$(CXX_STANDARD)' \
144 AR='$(build_AR)' NM='$(build_NM)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' \
145 DEBUG='$(DEBUG)' \
146 ./gen_id '$(BUILD_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
147
148 $(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(host_CXX)' CXX_STANDARD='$(CXX_STANDARD)' \
149 CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' CXXFLAGS='$(CXXFLAGS)' LDFLAGS='$(LDFLAGS)' \
150 AR='$(host_AR)' NM='$(host_NM)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' \
151 DEBUG='$(DEBUG)' LTO='$(LTO)' \
152 ./gen_id '$(HOST_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
153
154 boost_packages_$(NO_BOOST) = $(boost_packages)
155
156 qrencode_packages_$(NO_QR) = $(qrencode_$(host_os)_packages)
157
158 qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) $(qrencode_packages_)
159 qt_native_packages_$(NO_QT) = $(qt_native_packages)
160
161 wallet_packages_$(NO_WALLET) = $(sqlite_packages)
162
163 zmq_packages_$(NO_ZMQ) = $(zmq_packages)
164 ipc_packages_$(NO_IPC) = $(ipc_packages)
165 usdt_packages_$(NO_USDT) = $(usdt_$(host_os)_packages)
166
167 packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(boost_packages_) $(qt_packages_) $(wallet_packages_) $(usdt_packages_)
168 native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) $(qt_native_packages_)
169
170 ifneq ($(zmq_packages_),)
171 packages += $(zmq_packages)
172 endif
173
174 ifneq ($(ipc_packages_),)
175 packages += $(ipc_packages)
176 native_packages += $(multiprocess_native_packages)
177 endif
178
179 all_packages = $(packages) $(native_packages)
180
181 meta_depends = Makefile config.guess config.sub funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
182
183 include funcs.mk
184
185 final_build_id_long+=$(shell $(build_SHA256SUM) toolchain.cmake.in)
186 final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))
187 $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages)
188 rm -rf $(@D)
189 mkdir -p $(@D)
190 echo copying packages: $^
191 echo to: $(@D)
192 cd $(@D); $(foreach package,$^, $(build_TAR) xf $($(package)_cached); )
193 echo To build Bitcoin Core with these packages, pass \'--toolchain $(@D)/toolchain.cmake\' to the first CMake invocation.
194 touch $@
195
196 ifeq ($(host),$(build))
197 crosscompiling=FALSE
198 else
199 crosscompiling=TRUE
200 endif
201
202 $(host_prefix)/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_$(final_build_id)
203 @mkdir -p $(@D)
204 sed -e 's|@depends_crosscompiling@|$(crosscompiling)|' \
205 -e 's|@host@|$(host)|' \
206 -e 's|@host_system_name@|$($(host_os)_cmake_system_name)|' \
207 -e 's|@host_system_version@|$($(host_os)_cmake_system_version)|' \
208 -e 's|@host_arch@|$(host_arch)|' \
209 -e 's|@CC@|$(host_CC)|' \
210 -e 's|@CXX@|$(host_CXX)|' \
211 -e 's|@OSX_SDK@|$(OSX_SDK)|' \
212 -e 's|@AR@|$(host_AR)|' \
213 -e 's|@RANLIB@|$(host_RANLIB)|' \
214 -e 's|@STRIP@|$(host_STRIP)|' \
215 -e 's|@OBJCOPY@|$(host_OBJCOPY)|' \
216 -e 's|@OBJDUMP@|$(host_OBJDUMP)|' \
217 -e 's|@CFLAGS@|$(strip $(host_CFLAGS))|' \
218 -e 's|@CFLAGS_RELEASE@|$(strip $(host_release_CFLAGS))|' \
219 -e 's|@CFLAGS_DEBUG@|$(strip $(host_debug_CFLAGS))|' \
220 -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS))|' \
221 -e 's|@CXXFLAGS_RELEASE@|$(strip $(host_release_CXXFLAGS))|' \
222 -e 's|@CXXFLAGS_DEBUG@|$(strip $(host_debug_CXXFLAGS))|' \
223 -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS))|' \
224 -e 's|@CPPFLAGS_RELEASE@|$(strip $(host_release_CPPFLAGS))|' \
225 -e 's|@CPPFLAGS_DEBUG@|$(strip $(host_debug_CPPFLAGS))|' \
226 -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS))|' \
227 -e 's|@LDFLAGS_RELEASE@|$(strip $(host_release_LDFLAGS))|' \
228 -e 's|@LDFLAGS_DEBUG@|$(strip $(host_debug_LDFLAGS))|' \
229 -e 's|@qt_packages@|$(qt_packages_)|' \
230 -e 's|@qrencode_packages@|$(qrencode_packages_)|' \
231 -e 's|@zmq_packages@|$(zmq_packages_)|' \
232 -e 's|@wallet_packages@|$(wallet_packages_)|' \
233 -e 's|@usdt_packages@|$(usdt_packages_)|' \
234 -e 's|@ipc_packages@|$(ipc_packages_)|' \
235 $< > $@
236 touch $@
237
238 define check_or_remove_cached
239 mkdir -p $(BASE_CACHE)/$(host)/$(package) && cd $(BASE_CACHE)/$(host)/$(package); \
240 $(build_SHA256SUM) -c $($(package)_cached_checksum) >/dev/null 2>/dev/null || \
241 ( rm -f $($(package)_cached_checksum); \
242 if test -f "$($(package)_cached)"; then echo "Checksum mismatch for $(package). Forcing rebuild.."; rm -f $($(package)_cached_checksum) $($(package)_cached); fi )
243 endef
244
245 define check_or_remove_sources
246 mkdir -p $($(package)_source_dir); cd $($(package)_source_dir); \
247 test -f $($(package)_fetched) && ( $(build_SHA256SUM) -c $($(package)_fetched) >/dev/null 2>/dev/null || \
248 ( echo "Checksum missing or mismatched for $(package) source. Forcing re-download."; \
249 rm -f $($(package)_all_sources) $($(1)_fetched))) || true
250 endef
251
252 check-packages:
253 @$(foreach package,$(all_packages),$(call check_or_remove_cached,$(package));)
254 check-sources:
255 @$(foreach package,$(all_packages),$(call check_or_remove_sources,$(package));)
256
257 $(host_prefix)/toolchain.cmake: check-packages
258
259 check-packages: check-sources
260
261 clean-all: clean
262 @rm -rf $(SOURCES_PATH) x86_64* i686* mips* arm* aarch64* powerpc* riscv32* riscv64* s390x*
263
264 clean:
265 @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) *.log
266
267 install: check-packages $(host_prefix)/toolchain.cmake
268
269
270 download-one: check-sources $(all_sources)
271
272 download-osx:
273 @$(MAKE) -s HOST=x86_64-apple-darwin download-one
274 download-linux:
275 @$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one
276 download-win:
277 @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one
278 download: download-osx download-linux download-win
279
280 $(foreach package,$(all_packages),$(eval $(call ext_add_stages,$(package))))
281
282 .PHONY: install cached clean clean-all download-one download-osx download-linux download-win download check-packages check-sources
283 .PHONY: FORCE
284 $(V).SILENT:
285