Makefile raw

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