Skip to content

Commit 1dec09b

Browse files
committed
depends: add shared dependency builder
See the README's in depends for documentation
1 parent 36065cc commit 1dec09b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+4992
-0
lines changed

depends/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SDKs/
2+
work/
3+
built/
4+
sources/
5+
config.site

depends/Makefile

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
.NOTPARALLEL :
2+
3+
SOURCES_PATH ?= $(BASEDIR)/sources
4+
BASE_CACHE ?= $(BASEDIR)/built
5+
SDK_PATH ?= $(BASEDIR)/SDKs
6+
NO_QT ?=
7+
NO_WALLET ?=
8+
NO_UPNP ?=
9+
10+
BUILD = $(shell ./config.guess)
11+
HOST ?= $(BUILD)
12+
PATCHES_PATH = $(BASEDIR)/patches
13+
BASEDIR = $(CURDIR)
14+
HASH_LENGTH:=11
15+
16+
host:=$(BUILD)
17+
ifneq ($(HOST),)
18+
host:=$(HOST)
19+
host_toolchain:=$(HOST)-
20+
endif
21+
22+
base_build_dir=$(BASEDIR)/work/build
23+
base_staging_dir=$(BASEDIR)/work/staging
24+
canonical_host:=$(shell ./config.sub $(HOST))
25+
build:=$(shell ./config.sub $(BUILD))
26+
27+
build_arch =$(firstword $(subst -, ,$(build)))
28+
build_vendor=$(word 2,$(subst -, ,$(build)))
29+
full_build_os:=$(subst $(build_arch)-$(build_vendor)-,,$(build))
30+
build_os:=$(findstring linux,$(full_build_os))
31+
build_os+=$(findstring darwin,$(full_build_os))
32+
build_os:=$(strip $(build_os))
33+
ifeq ($(build_os),)
34+
build_os=$(full_build_os)
35+
endif
36+
37+
host_arch=$(firstword $(subst -, ,$(canonical_host)))
38+
host_vendor=$(word 2,$(subst -, ,$(canonical_host)))
39+
full_host_os:=$(subst $(host_arch)-$(host_vendor)-,,$(canonical_host))
40+
host_os:=$(findstring linux,$(full_host_os))
41+
host_os+=$(findstring darwin,$(full_host_os))
42+
host_os+=$(findstring mingw32,$(full_host_os))
43+
host_os:=$(strip $(host_os))
44+
ifeq ($(host_os),)
45+
host_os=$(full_host_os)
46+
endif
47+
48+
$(host_arch)_$(host_os)_prefix=$(BASEDIR)/$(host)
49+
$(host_arch)_$(host_os)_host=$(host)
50+
host_prefix=$($(host_arch)_$(host_os)_prefix)
51+
build_prefix=$(host_prefix)/native
52+
build_host=$(build)
53+
54+
AT_$(V):=
55+
AT_:=@
56+
AT:=$(AT_$(V))
57+
58+
all: install
59+
60+
include hosts/$(host_os).mk
61+
include hosts/default.mk
62+
include builders/$(build_os).mk
63+
include builders/default.mk
64+
include packages/packages.mk
65+
66+
qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages)
67+
qt_native_packages_$(NO_QT) = $(qt_native_packages)
68+
wallet_packages_$(NO_WALLET) = $(wallet_packages)
69+
upnp_packages_$(NO_UPNP) = $(upnp_packages)
70+
71+
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_)
72+
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) $(qt_native_packages_)
73+
all_packages = $(packages) $(native_packages)
74+
75+
meta_depends = Makefile builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
76+
77+
$(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain)
78+
79+
include funcs.mk
80+
81+
toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin)
82+
final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in)
83+
final_build_id+=$(shell echo -n $(final_build_id_long) | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))
84+
$(host_prefix)/.stamp_$(final_build_id): | $(native_packages) $(packages)
85+
$(AT)rm -rf $(@D)
86+
$(AT)mkdir -p $(@D)
87+
$(AT)echo copying packages: $|
88+
$(AT)echo to: $(@D)
89+
$(AT)cd $(@D); $(foreach package,$|, tar xf $($(package)_cached); )
90+
$(AT)touch $@
91+
92+
$(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_build_id)
93+
$(AT)@mkdir -p $(@D)
94+
$(AT)sed -e 's|@HOST@|$(host)|' \
95+
-e 's|@CC@|$(toolchain_path)$(host_CC)|' \
96+
-e 's|@CXX@|$(toolchain_path)$(host_CXX)|' \
97+
-e 's|@AR@|$(toolchain_path)$(host_AR)|' \
98+
-e 's|@RANLIB@|$(toolchain_path)$(host_RANLIB)|' \
99+
-e 's|@NM@|$(toolchain_path)$(host_NM)|' \
100+
-e 's|@STRIP@|$(toolchain_path)$(host_STRIP)|' \
101+
-e 's|@build_os@|$(build_os)|' \
102+
-e 's|@host_os@|$(host_os)|' \
103+
-e 's|@CFLAGS@|$(host_CFLAGS)|' \
104+
-e 's|@CXXFLAGS@|$(host_CXXFLAGS)|' \
105+
-e 's|@LDFLAGS@|$(host_LDFLAGS)|' \
106+
-e 's|@no_qt@|$(NO_QT)|' \
107+
-e 's|@no_wallet@|$(NO_WALLET)|' \
108+
-e 's|@no_upnp@|$(NO_UPNP)|' \
109+
$< > $@
110+
$(AT)touch $@
111+
112+
install: $(host_prefix)/share/config.site
113+
download: $(all_sources)
114+
.PHONY: install cached

depends/README

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
This is a system of building and caching dependencies necessary for building
2+
Bitcoin.
3+
4+
There are several features that make it different from most similar systems:
5+
6+
- It is designed to be builder and host agnostic
7+
8+
In theory, binaries for any target OS/architecture can be created, from a
9+
builder running any OS/architecture. In practice, build-side tools must be
10+
specified when the defaults don't fit, and packages must be ammended to work
11+
on new hosts. For now, a build architecture of x86_64 is assumed, either on
12+
Linux or OSX.
13+
14+
- No reliance on timestamps
15+
16+
File presence is used to determine what needs to be built. This makes the
17+
results distributable and easily digestable by automated builders.
18+
19+
- Each build only has its specified dependencies available at build-time.
20+
21+
For each build, the sysroot is wiped and the (recursive) dependencies are
22+
installed. This makes each build deterministic, since there will never be any
23+
unknown files available to cause side-effects.
24+
25+
- Each package is cached and only rebuilt as needed.
26+
27+
Before building, a unique build-id is generated for each package. This id
28+
consists of a hash of all files used to build the package (Makefiles, packages,
29+
etc), and as well as a hash of the same data for each recursive dependency. If
30+
any portion of a package's build recipe changes, it will be rebuilt as well as
31+
any other package that depends on it. If any of the main makefiles (Makefile,
32+
funcs.mk, etc) are changed, all packages will be rebuilt. After building, the
33+
results are cached into a tarball that can be re-used and distributed.
34+
35+
- Package build results are (relatively) deterministic.
36+
37+
Each package is configured and patched so that it will yield the same
38+
build-results with each consequent build, within a reasonable set of
39+
constraints. Some things like timestamp insertion are unavoidable, and are
40+
beyond the scope of this system. Additionally, the toolchain itself must be
41+
capable of deterministic results. When revisions are properly bumped, a cached
42+
build should represent an exact single payload.
43+
44+
- Sources are fetched and verified automatically
45+
46+
Each package must define its source location and checksum. The build will fail
47+
if the fetched source does not match. Sources may be pre-seeded and/or cached
48+
as desired.
49+
50+
- Self-cleaning
51+
52+
Build and staging dirs are wiped after use, and any previous version of a
53+
cached result is removed following a successful build. Automated builders
54+
should be able to build each revision and store the results with no further
55+
intervention.

depends/README.packages

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
Each recipe consists of 3 main parts: defining identifiers, setting build
2+
variables, and defining build commands.
3+
4+
The package "mylib" will be used here as an example
5+
6+
General tips:
7+
mylib_foo is written as $(package)_foo in order to make recipes more similar.
8+
9+
Identifiers:
10+
Each package is required to define at least these variables:
11+
$(package)_version:
12+
Version of the upstream library or program. If there is no version, a
13+
placeholder such as 1.0 can be used.
14+
$(package)_download_path:
15+
Location of the upstream source, without the file-name. Usually http or
16+
ftp.
17+
$(package)_file_name:
18+
The upstream source filename available at the download path.
19+
$(package)_sha256_hash:
20+
The sha256 hash of the upstream file
21+
22+
These variables are optional:
23+
$(package)_build_subdir:
24+
cd to this dir before running configure/build/stage commands.
25+
$(package)_download_file:
26+
The file-name of the upstream source if it differs from how it should be
27+
stored locally. This can be used to avoid storing file-names with strange
28+
characters.
29+
$(package)_dependencies:
30+
Names of any other packages that this one depends on.
31+
$(package)_patches:
32+
Filenames of any patches needed to build the package
33+
34+
35+
Build Variables:
36+
After defining the main identifiers, build variables may be added or customized
37+
before running the build commands. They should be added to a function called
38+
$(package)_set_vars. For example:
39+
40+
define $(package)_set_vars
41+
...
42+
endef
43+
44+
Most variables can be prefixed with the host, architecture, or both, to make
45+
the modifications specific to that case. For example:
46+
47+
Universal: $(package)_cc=gcc
48+
Linux only: $(package)_linux_cc=gcc
49+
x86_64 only: $(package)_x86_64_cc = gcc
50+
x86_64 linux only: $(package)_x86_64_linux_cc = gcc
51+
52+
These variables may be set to override or append their default values.
53+
$(package)_cc
54+
$(package)_cxx
55+
$(package)_objc
56+
$(package)_objcxx
57+
$(package)_ar
58+
$(package)_ranlib
59+
$(package)_libtool
60+
$(package)_nm
61+
$(package)_cflags
62+
$(package)_cxxflags
63+
$(package)_ldflags
64+
$(package)_cppflags
65+
$(package)_config_env
66+
$(package)_build_env
67+
$(package)_stage_env
68+
69+
The *_env variables are used to add environment variables to the respective
70+
commands.
71+
72+
Other variables may be defined as needed.
73+
74+
Build commands:
75+
76+
For each build, a unique build dir and staging dir are created. For example,
77+
work/build/mylib/1.0-1adac830f6e and work/staging/mylib/1.0-1adac830f6e.
78+
79+
The following build commands are available for each recipe:
80+
81+
$(package)_fetch_cmds:
82+
Runs from: build dir
83+
Fetch the source file. If undefined, it will be fetched and verified
84+
against its hash.
85+
$(package)_extract_cmds:
86+
Runs from: build dir
87+
Verify the source file against its hash and extract it. If undefined, the
88+
source is assumed to be a tarball.
89+
$(package)_preprocess_cmds:
90+
Runs from: build dir/$(package)_build_subdir
91+
Preprocess the source as necessary. If undefined, does nothing.
92+
$(package)_config_cmds:
93+
Runs from: build dir/$(package)_build_subdir
94+
Configure the source. If undefined, does nothing.
95+
$(package)_build_cmds:
96+
Runs from: build dir/$(package)_build_subdir
97+
Build the source. If undefined, does nothing.
98+
$(package)_stage_cmds:
99+
Runs from: build dir/$(package)_build_subdir
100+
Stage the build results. If undefined, does nothing.
101+
102+
The following variables are available for each recipe:
103+
$(1)_staging_dir: package's destination sysroot path
104+
$(1)_staging_prefix_dir: prefix path inside of the package's staging dir
105+
$(1)_extract_dir: path to the package's extracted sources
106+
$(1)_build_dir: path where configure/build/stage commands will be run
107+
$(1)_patch_dir: path where the package's patches (if any) are found
108+
109+
Notes on build commands:
110+
111+
For packages built with autotools, $($(package)_autoconf) can be used in the
112+
configure step to (usually) correctly configure automatically. Any
113+
$($(package)_config_opts) will be appended.
114+
115+
Most autotools projects can be properly staged using:
116+
$(MAKE) DESTDIR=$($(package)_staging_dir) install

depends/README.usage

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
To build dependencies for the current arch+OS:
2+
make
3+
To build for another arch/OS:
4+
make HOST=host-platform-triplet && make HOST=host-platform-triplet
5+
(For example: make HOST=i686-w64-mingw32 -j4)
6+
7+
A prefix will be generated that's suitable for plugging into Bitcoin's
8+
configure. In the above example, a dir named i686-w64-mingw32 will be
9+
created. To use it for Bitcoin:
10+
11+
./configure --prefix=`pwd`/depends/i686-w64-mingw32
12+
13+
No other options are needed, the paths are automatically configured.
14+
15+
Dependency Options:
16+
The following can be set when running make: make FOO=bar
17+
18+
SOURCES_PATH: downloaded sources will be placed here
19+
BASE_CACHE: built packages will be placed here
20+
SDK_PATH: Path where sdk's can be found (used by OSX)
21+
NO_QT: Don't download/build/cache qt and its dependencies
22+
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
23+
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
24+
25+
If some packages are not built, for example 'make NO_WALLET=1', the appropriate
26+
options will be passed to bitcoin's configure. In this case, --disable-wallet.
27+
28+
Additional targets:
29+
download: run 'make download' to fetch sources without building them

depends/builders/darwin.mk

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
build_darwin_CC: = $(shell xcrun -f clang)
2+
build_darwin_CXX: = $(shell xcrun -f clang++)
3+
build_darwin_AR: = $(shell xcrun -f ar)
4+
build_darwin_RANLIB: = $(shell xcrun -f ranlib)
5+
build_darwin_STRIP: = $(shell xcrun -f strip)
6+
build_darwin_OTOOL: = $(shell xcrun -f otool)
7+
build_darwin_NM: = $(shell xcrun -f nm)
8+
build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool)
9+
build_darwin_SHA256SUM = shasum -a 256
10+
build_darwin_DOWNLOAD = curl -L -o
11+
12+
#darwin host on darwin builder. overrides darwin host preferences.
13+
darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION)
14+
darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION)
15+
darwin_AR:=$(shell xcrun -f ar)
16+
darwin_RANLIB:=$(shell xcrun -f ranlib)
17+
darwin_STRIP:=$(shell xcrun -f strip)
18+
darwin_LIBTOOL:=$(shell xcrun -f libtool)
19+
darwin_OTOOL:=$(shell xcrun -f otool)
20+
darwin_NM:=$(shell xcrun -f nm)
21+
darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool)
22+
darwin_native_toolchain=

depends/builders/default.mk

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
default_build_CC = gcc
2+
default_build_CXX = g++
3+
default_build_AR = ar
4+
default_build_RANLIB = ranlib
5+
default_build_STRIP = strip
6+
default_build_NM = nm
7+
default_build_OTOOL = otool
8+
default_build_INSTALL_NAME_TOOL = install_name_tool
9+
10+
define add_build_tool_func
11+
build_$(build_os)_$1 ?= $$(default_build_$1)
12+
build_$(build_arch)_$(build_os)_$1 ?= $$(build_$(build_os)_$1)
13+
build_$1=$$(build_$(build_arch)_$(build_os)_$1)
14+
endef
15+
$(foreach var,CC CXX AR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL,$(eval $(call add_build_tool_func,$(var))))
16+
define add_build_flags_func
17+
build_$(build_arch)_$(build_os)_$1 += $(build_$(build_os)_$1)
18+
build_$1=$$(build_$(build_arch)_$(build_os)_$1)
19+
endef
20+
$(foreach flags, CFLAGS CXXFLAGS LDFLAGS, $(eval $(call add_build_flags_func,$(flags))))

depends/builders/linux.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build_linux_SHA256SUM = sha256sum
2+
build_linux_DOWNLOAD = wget -nv -O

0 commit comments

Comments
 (0)