forked from paritytech/polkadot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dockerfile
338 lines (271 loc) · 12.8 KB
/
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
FROM rust:1.54.0-slim-bullseye
# ---- Initial definitions
ENV DEBIAN_FRONTEND=noninteractive
ARG APT_INSTALL="apt install --assume-yes --quiet --no-install-recommends"
# https://wiki.gentoo.org/wiki/Embedded_Handbook/General/Introduction#Environment_variables
ARG RUST_TARGET=x86_64-unknown-linux-musl \
TARGET=x86_64-linux-musl \
HOST=x86_64-linux-gnu
# ---- Rust toolchains
RUN rustup target add $RUST_TARGET && \
rustup toolchain install --profile minimal nightly && \
rustup target add wasm32-unknown-unknown --toolchain nightly
# --- Setup for building C/C++ dependencies
RUN apt update && \
$APT_INSTALL curl unzip cmake make build-essential wget pkg-config && \
make --version && \
curl --version && \
unzip -v && \
cmake --version && \
wget --version && \
pkg-config --version
ENV PKG_CONFIG_ALL_STATIC=true \
PKG_CONFIG_ALLOW_CROSS=true
# ---- musl
# Default to the same GCC version as the one used by default in our version of
# musl-cross-make
# e.g. https://github.com/richfelker/musl-cross-make/blob/75e6c618adc9dde2cdcd0522ef40adf75a6bffe7/Makefile#L6
ARG GCC_MAJOR_VERSION=9 \
GCC_MINOR_VERSION=2.0 \
CROSS_MAKE_VERSION=0.9.9 \
MUSL=/usr/local/musl
ENV GCC_VERSION=$GCC_MAJOR_VERSION.$GCC_MINOR_VERSION \
TARGET_HOME=$MUSL/$TARGET \
HIJACK_AR=$MUSL/bin/ar \
HIJACK_AS=$MUSL/bin/as \
HIJACK_LD=$MUSL/bin/ld \
HIJACK_STRIP=$MUSL/bin/strip \
HIJACK_CC=$MUSL/bin/cc \
HIJACK_CPP=$MUSL/bin/c++ \
HIJACK_GNUCC=$MUSL/bin/gnu-cc \
HIJACK_GNUCXX=$MUSL/bin/gnu-cxx
# --enable-default-pie: https://www.openwall.com/lists/musl/2017/12/21/1
# If you build gcc with --enable-default-pie, musl libc.a will also end up as PIC by default.
# --enable-initfini-array: https://github.com/richfelker/musl-cross-make/commit/3398364d6e3251cd097024182a8cb9f667c23bda
RUN export CROSS_MAKE_FOLDER=musl-cross-make-$CROSS_MAKE_VERSION && \
export CROSS_MAKE_SOURCE=$CROSS_MAKE_FOLDER.zip && \
cd /tmp && curl -Lsq https://github.com/richfelker/musl-cross-make/archive/v$CROSS_MAKE_VERSION.zip -o $CROSS_MAKE_SOURCE && \
echo "6cbe2f6ce92e7f8f3973786aaf0b990d0db380c0e0fc419a7d516df5bb03c891 $CROSS_MAKE_SOURCE" | sha256sum --check && \
unzip -q $CROSS_MAKE_SOURCE && rm $CROSS_MAKE_SOURCE && \
cd $CROSS_MAKE_FOLDER && \
echo "OUTPUT = $MUSL\nTARGET = $TARGET\nCOMMON_CONFIG += CFLAGS=\"-g0 -Os\" CXXFLAGS=\"-g0 -Os\" LDFLAGS=\"-s\"\nGCC_CONFIG += --enable-languages=c,c++\nGCC_CONFIG += --enable-default-pie\nGCC_CONFIG += --enable-initfini-array\nGCC_VER=$GCC_VERSION" | tee config.mak && \
make -j$(nproc) && make install && \
ln -s $MUSL/bin/$TARGET-ar $HIJACK_AR && \
ln -s $MUSL/bin/$TARGET-as $HIJACK_AS && \
ln -s $MUSL/bin/$TARGET-ld $HIJACK_LD && \
ln -s $MUSL/bin/$TARGET-strip $HIJACK_STRIP && \
cd .. && rm -rf $CROSS_MAKE_FOLDER
# ---- Compiler setup
# We want the headers from libstdc++-dev for compiling the C++ applications e.g.
# RocksDB
RUN $APT_INSTALL git libstdc++-$GCC_MAJOR_VERSION-dev
ENV C_INCLUDE_PATH=$TARGET_HOME/include:$MUSL/lib/gcc/$TARGET/$GCC_VERSION/include
ENV CC_EXE=$MUSL/bin/$TARGET-gcc \
CXX_EXE=$MUSL/bin/$TARGET-g++ \
CC=$MUSL/bin/gcc \
CXX=$MUSL/bin/g++ \
CPLUS_INCLUDE_PATH=$C_INCLUDE_PATH \
PATH=$MUSL/bin:$PATH
# since musl-gcc already adds the relevant includes, nostdinc and nostdinc++ are
# used to ensure system-level headers are not looked at
# rpath-link is used to prioritize the libraries' location at link time
# -fPIC enables Position Independent Code which is a requirement for producing
# fully static binaries
ENV BASE_CFLAGS="-v -static --static -nostdinc -nostdinc++ -static-libgcc -static-libstdc++ -fPIC -Wl,-rpath-link,$TARGET_HOME/lib -Wl,--no-dynamic-linker -Wl,-static -L$TARGET_HOME/lib"
ENV BASE_CXXFLAGS="$BASE_CFLAGS -I$TARGET_HOME/include/c++/$GCC_VERSION -I$TARGET_HOME/include/c++/$GCC_VERSION/$TARGET"
# Since *ALL* objects should be compiled statically and have the flags we want,
# we'll hijack the compiler executables here with a custom script which forces
# our desired options and filters out unwanted ones regardless of what each
# individual application wants, as opposed to e.g. relying on CFLAGS which might
# be ignored by the applications' build scripts.
COPY ./generate_wrapper /generate_wrapper
RUN /generate_wrapper "$CC_EXE $BASE_CFLAGS" > $CC && \
chmod +x $CC && \
ln -s $CC $HIJACK_CC && \
ln -s $CC $HIJACK_GNUCC && \
/generate_wrapper "$CXX_EXE $BASE_CXXFLAGS" > $CXX && \
chmod +x $CXX && \
ln -s $CC $HIJACK_CPP && \
ln -s $CC $HIJACK_GNUCXX
# ---- ZLib
# used in OpenSSL and RocksDB
ARG ZLIB_VERSION=1.2.11
RUN export ZLIB_FOLDER=zlib-$ZLIB_VERSION && \
export ZLIB_SOURCE=$ZLIB_FOLDER.tar.gz && \
cd /tmp && curl -sqLO https://zlib.net/$ZLIB_SOURCE && \
echo "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 $ZLIB_SOURCE" | sha256sum --check && \
tar xzf $ZLIB_SOURCE && rm $ZLIB_SOURCE && \
cd $ZLIB_FOLDER && \
./configure \
--static \
--prefix=$TARGET_HOME && \
make -j$(nproc) && make install && \
cd .. && rm -rf $ZLIB_FOLDER
ENV Z_STATIC=1 \
Z_LIB_DIR=$TARGET_HOME/lib
# ---- OpenSSL
# used in Substrate
ARG OPENSSL_VERSION=1.0.2u \
OPENSSL_ARCH=linux-x86_64
RUN export OPENSSL_FOLDER=openssl-$OPENSSL_VERSION && \
export OPENSSL_SOURCE=$OPENSSL_FOLDER.tar.gz && \
cd /tmp && curl -sqO https://www.openssl.org/source/$OPENSSL_SOURCE && \
echo "ecd0c6ffb493dd06707d38b14bb4d8c2288bb7033735606569d8f90f89669d16 $OPENSSL_SOURCE" | sha256sum --check && \
tar xzf $OPENSSL_SOURCE && rm $OPENSSL_SOURCE && \
cd $OPENSSL_FOLDER && \
./Configure \
$OPENSSL_ARCH \
-static \
no-shared \
--prefix=$TARGET_HOME && \
make -j$(nproc) && make install && \
cd .. && rm -rf $OPENSSL_FOLDER
ENV OPENSSL_STATIC=1 \
OPENSSL_DIR=$TARGET_HOME \
OPENSSL_INCLUDE_DIR=$TARGET_HOME/include \
DEP_OPENSSL_INCLUDE=$TARGET_HOME/include \
OPENSSL_LIB_DIR=$TARGET_HOME/lib
# ---- Jemalloc
# used in parity-util-mem
RUN $APT_INSTALL autoconf automake autotools-dev libtool
ARG LIBUNWIND_VERSION=1.6.0-rc2
RUN export LIBUNWIND_FOLDER=libunwind-$LIBUNWIND_VERSION && \
export LIBUNWIND_SOURCE=$LIBUNWIND_FOLDER.tar.gz && \
cd /tmp && curl -sqLO https://github.com/libunwind/libunwind/releases/download/v$LIBUNWIND_VERSION/$LIBUNWIND_SOURCE && \
echo "b5bd33aa9538cccc66a19faa95c943e160fdb58dab8e4518131a0bd936c6c0f4 $LIBUNWIND_SOURCE" | sha256sum --check && \
tar xzf $LIBUNWIND_SOURCE && rm $LIBUNWIND_SOURCE && \
cd $LIBUNWIND_FOLDER && \
# revert https://github.com/libunwind/libunwind/commit/f1684379dfaf8018d5d4c1945e292a56d0fab245
# use -lgcc because we don't have gcc_s from musl-cross-make
# gcc_s is the shared library counterpart of gcc_eh according to https://gitlab.kitware.com/cmake/cmake/-/merge_requests/1460
sed -e 's/-lgcc_s/-lgcc/' -i configure.ac && \
autoreconf -i && \
./configure \
--build=$HOST \
--host=$TARGET \
--enable-static \
--disable-shared \
--prefix=$TARGET_HOME && \
make -j$(nproc) && make install prefix=$TARGET_HOME && \
cd .. && rm -rf $LIBUNWIND_FOLDER
ARG JEMALLOC_VERSION=5.2.1
RUN export JEMALLOC_FOLDER=jemalloc-$JEMALLOC_VERSION && \
export JEMALLOC_SOURCE=$JEMALLOC_FOLDER.tar.bz2 && \
cd /tmp && curl -sqLO https://github.com/jemalloc/jemalloc/releases/download/$JEMALLOC_VERSION/$JEMALLOC_SOURCE && \
echo "34330e5ce276099e2e8950d9335db5a875689a4c6a56751ef3b1d8c537f887f6 $JEMALLOC_SOURCE" | sha256sum --check && \
tar xf $JEMALLOC_SOURCE && rm $JEMALLOC_SOURCE && \
cd $JEMALLOC_FOLDER && \
./configure \
--build=$HOST \
--host=$TARGET \
--with-static-libunwind=$TARGET_HOME/lib/libunwind.a \
--disable-libdl \
--disable-initial-exec-tls \
--prefix=$TARGET_HOME && \
make -j$(nproc) build_lib_static && \
make install_lib_static && \
cd .. && rm -rf $JEMALLOC_FOLDER
ENV JEMALLOC_OVERRIDE=$TARGET_HOME/lib/libjemalloc.a
# ---- RocksDB
# used in Substrate
# from RocksDB's dependencies, only snappy is compiled due to:
# https://github.com/paritytech/parity-common/blob/30a879f4401fa4eac7f4d70be1038d7933e215a1/kvdb-rocksdb/Cargo.toml#L22
# This is the version used for rust-rocksdb v0.17.0
# Should the rust-rocksdb version used by Substrate change, revisit this
ARG SNAPPY_VERSION=1.1.8
RUN export SNAPPY_FOLDER=snappy-$SNAPPY_VERSION && \
export SNAPPY_SOURCE=$SNAPPY_VERSION.tar.gz && \
cd /tmp && curl -sqLO https://github.com/google/snappy/archive/refs/tags/$SNAPPY_SOURCE && \
echo "16b677f07832a612b0836178db7f374e414f94657c138e6993cbfc5dcc58651f $SNAPPY_SOURCE" | sha256sum --check && \
tar xzf $SNAPPY_SOURCE && rm $SNAPPY_SOURCE && \
cd $SNAPPY_FOLDER && mkdir build && cd build && \
cmake \
-DBUILD_SHARED_LIBS=0 \
-DBUILD_STATIC_LIBS=1 \
-DSNAPPY_BUILD_TESTS=0 \
-DSNAPPY_BUILD_BENCHMARKS=0 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$TARGET_HOME \
.. && \
make && make install && \
cd ../.. && rm -rf $SNAPPY_FOLDER
ENV SNAPPY_STATIC=1 \
SNAPPY_LIB_DIR=$TARGET_HOME/lib
# This SHA should not matter to much as gflags is only a support library for
# building RocksDB. It does not necessarily needs to be revisited in case the
# RocksDB version changes.
# The following SHA is the latest one from master as of 2021-09-09.
ARG GFLAGS_SHA=827c769e5fc98e0f2a34c47cef953cc6328abced
RUN export GFLAGS_FOLDER=gflags-$GFLAGS_SHA && \
export GFLAGS_SOURCE=$GFLAGS_SHA.zip && \
cd /tmp && curl -sqLO https://github.com/gflags/gflags/archive/$GFLAGS_SOURCE && \
echo "cfdba0f2f17e8b1ff75c98113d5080d8ec016148426abcc19130864e2952d7bd $GFLAGS_SOURCE" | sha256sum --check && \
unzip -q $GFLAGS_SOURCE && rm $GFLAGS_SOURCE && \
cd $GFLAGS_FOLDER && mkdir build && cd build && \
cmake \
-DBUILD_SHARED_LIBS=0 \
-DBUILD_STATIC_LIBS=1 \
-DBUILD_TESTING=0 \
-DGFLAGS_INSTALL_STATIC_LIBS=1 \
-DBUILD_gflags_LIB=0 \
-DCMAKE_INSTALL_PREFIX=$TARGET_HOME \
.. && \
make && make install && \
mv $TARGET_HOME/lib/libgflags_nothreads.a $TARGET_HOME/lib/libgflags.a && \
cd ../.. && rm -rf gflags
# This is the version used for rust-rocksdb v0.17.0
# Should the rust-rocksdb version used by Substrate change, revisit this
ARG ROCKSDB_VERSION=6.20.3
# We'll opt out of jemalloc and tcmalloc so that, for now, we'll have less
# components to worry about; those libraries are not strictly necessary for
# RocksDB to function and could be enabled later
RUN export ROCKSDB_FOLDER=rocksdb-$ROCKSDB_VERSION && \
export ROCKSDB_SOURCE=v$ROCKSDB_VERSION.tar.gz && \
cd /tmp && curl -sqLO https://github.com/facebook/rocksdb/archive/refs/tags/$ROCKSDB_SOURCE && \
echo "c6502c7aae641b7e20fafa6c2b92273d935d2b7b2707135ebd9a67b092169dca $ROCKSDB_SOURCE" | sha256sum --check && \
tar xzf $ROCKSDB_SOURCE && rm $ROCKSDB_SOURCE && \
cd $ROCKSDB_FOLDER && \
PORTABLE=1 DISABLE_JEMALLOC=1 make static_lib && \
mv librocksdb.a $TARGET_HOME/lib && \
mv include/* $TARGET_HOME/include && \
cd .. && rm -rf $ROCKSDB_FOLDER
ENV ROCKSDB_STATIC=1 \
ROCKSDB_LIB_DIR=$TARGET_HOME/lib \
ROCKSDB_INCLUDE_DIR=$TARGET_HOME/include \
ROCKSDB_DISABLE_JEMALLOC=1 \
ROCKSDB_DISABLE_TCMALLOC=1
# ---- Polkadot
# libclang used for compile-time Rust build tools
RUN $APT_INSTALL libclang-dev
ENV RUST_TARGET_GCC_DIR=/usr/local/$TARGET/bin
ENV RUST_TARGET_GCC=$RUST_TARGET_GCC_DIR/musl-gcc \
PATH=$RUST_TARGET_GCC_DIR:$PATH
# unhijack the compiler executables because we'll no longer be compiling C
# directly for the final binary (C will still be compiled for Rust build tools
# but we don't care about which toolchain is used for that)
RUN mkdir -p $RUST_TARGET_GCC_DIR && \
mv $CC $RUST_TARGET_GCC && \
rm $CXX $HIJACK_AR $HIJACK_AS $HIJACK_LD $HIJACK_STRIP $HIJACK_CC $HIJACK_CPP $HIJACK_GNUCC $HIJACK_GNUCXX
ENV CC=
ENV CXX=
# https://doc.rust-lang.org/rustc/codegen-options/index.html#link-self-contained
# link-self-contained=no is used so that the rust compiler does not include the
# build target's c runtime when it's linking the executable, because we'll be
# using musl-cross-make's target c runtime instead, which was already used to
# compile all the libraries above
# https://doc.rust-lang.org/rustc/codegen-options/index.html#relocation-model
# relocation-model=pic is used for the same reason why we are using -fPIC in the
# C compiler's options
# note: musl-gcc will automatically be picked up for our target on
# $RUST_TARGET_GCC, thus why we do not need to specify a "runner" in the
# following configuration
RUN echo "[target.$RUST_TARGET]\nlinker = \"$RUST_TARGET_GCC\"\nrustflags=[\"-C\",\"target-feature=+crt-static\",\"-C\",\"link-self-contained=no\",\"-C\",\"prefer-dynamic=no\",\"-C\",\"relocation-model=pic\"]" > $CARGO_HOME/config
COPY . /app
WORKDIR /app
RUN RUST_BACKTRACE=full \
RUSTC_WRAPPER= \
WASM_BUILD_NO_COLOR=1 \
BINDGEN_EXTRA_CLANG_ARGS="--sysroot=$TARGET_HOME -target $TARGET" && \
cargo build --target $RUST_TARGET --release --verbose && \
mv /app/target/x86_64-unknown-linux-musl/release/polkadot /polkadot && \
rm -rf /app/*