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