Skip to content

Commit ef502dd

Browse files
authored
Add option to build with dynamic libc and c++, but static other dependencies; change static option name (#4597)
* Add option to build with dynamic libc and c++, but static boost and other dependencies * Improve options' documentation * Add CI for static-sans-stdlib * Merge the static builds using matrix, factor the check to a bash script, run on schedule + optional * Perform exact match on library names * Fix checks, pass binary to check on commandline * Fix label name * Improve comment * Fix ci-build * Simplify setting of static options * cmake: Rename the "static" options * CI: Update option names for semi-static * Remove remaining mentions of the old version of static options * Rename the static option once more
1 parent 8e2b256 commit ef502dd

File tree

6 files changed

+101
-34
lines changed

6 files changed

+101
-34
lines changed
+16-21
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
name: "static-build-test-p4c"
22

33
on:
4+
schedule:
5+
# Every day on midnight UTC
6+
- cron: "0 0 * * *"
47
push:
58
branches: [main]
69
pull_request:
710
branches: [main]
8-
merge_group:
9-
branches: [main]
1011

1112
# Cancel any preceding run on the pull request.
1213
concurrency:
@@ -16,11 +17,21 @@ concurrency:
1617
jobs:
1718
# Build a p4c release on Ubuntu 20.04.
1819
build-linux:
20+
# Only run on pull requests with the "run-static" label.
21+
if: ${{ github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'run-static') }}
22+
# Note: Actions have no real ternary condition operator, but this hack works because non-empty
23+
# strings are true.
24+
name: "Dynamic ${{ matrix.dynamic.glibc == 'ON' && 'glibc' || 'stdlib' }}"
25+
strategy:
26+
fail-fast: false
27+
matrix:
28+
dynamic: [{glibc: ON, stdlib: OFF}, {glibc: OFF, stdlib: ON}]
1929
runs-on: ubuntu-20.04
2030
env:
2131
IMAGE_TYPE: test
2232
CMAKE_UNITY_BUILD: ON
23-
BUILD_STATIC_RELEASE_SANS_GLIBC: ON
33+
STATIC_BUILD_WITH_DYNAMIC_GLIBC: "${{ matrix.dynamic.glibc }}"
34+
STATIC_BUILD_WITH_DYNAMIC_STDLIB: "${{ matrix.dynamic.stdlib }}"
2435
ENABLE_TEST_TOOLS: ON
2536
BUILD_GENERATOR: Ninja
2637
steps:
@@ -38,21 +49,5 @@ jobs:
3849
name: Build (Ubuntu 20.04)
3950
run: |
4051
sudo -E tools/ci-build.sh
41-
# Disabling these checks until we find a better way to build a fully static binary.
42-
# ldd ./build/p4c-bm2-psa 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
43-
# ldd ./build/p4c-bm2-ss 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
44-
# ldd ./build/p4c-dpdk 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
45-
# ldd ./build/p4c-ebpf 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
46-
# ldd ./build/p4c-pna-p4tc 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
47-
# ldd ./build/p4c-ubpf 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
48-
# ldd ./build/p4test 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
49-
# ldd ./build/p4testgen 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
50-
51-
! ldd ./build/p4c-bm2-psa 2>&1 | grep -E "libgc|libboost_iostreams"
52-
! ldd ./build/p4c-bm2-ss 2>&1 | grep -E "libgc|libboost_iostreams"
53-
! ldd ./build/p4c-dpdk 2>&1 | grep -E "libgc|libboost_iostreams"
54-
! ldd ./build/p4c-ebpf 2>&1 | grep -E "libgc|libboost_iostreams"
55-
! ldd ./build/p4c-pna-p4tc 2>&1 | grep -E "libgc|libboost_iostreams"
56-
! ldd ./build/p4c-ubpf 2>&1 | grep -E "libgc|libboost_iostreams"
57-
! ldd ./build/p4test 2>&1 | grep -E "libgc|libboost_iostreams"
58-
! ldd ./build/p4testgen 2>&1 | grep -E "libgc|libboost_iostreams"
52+
./tools/ci-check-static.sh ./build/p4c-bm2-ss ./build/p4c-dpdk ./build/p4c-ebpf \
53+
./build/p4c-pna-p4tc ./build/p4c-ubpf ./build/p4test ./build/p4testgen

CMakeLists.txt

+21-7
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,15 @@ OPTION (ENABLE_GC "Use libgc" ON)
4848
OPTION (ENABLE_MULTITHREAD "Use multithreading" OFF)
4949
OPTION (ENABLE_WERROR "Treat warnings as errors" OFF)
5050
OPTION (ENABLE_SANITIZERS "Enable sanitizers" OFF)
51-
OPTION (BUILD_STATIC_RELEASE_SANS_GLIBC
52-
"Build a (mostly) statically linked release binary. Glibc is linked dynamically." OFF
53-
)
54-
if (BUILD_STATIC_RELEASE_SANS_GLIBC)
51+
OPTION (STATIC_BUILD_WITH_DYNAMIC_GLIBC "Build a (mostly) statically linked release binary. \
52+
Glibc is linked dynamically. WARNING: This only works if all dependencies that depend on the C++ \
53+
standard library can be linked statically, otherwise the build will likely be broken and it will \
54+
likely depend on the standard libary anyway. If you have some non-static C++ dependencies, use \
55+
STATIC_BUILD_WITH_DYNAMIC_STDLIB." OFF)
56+
OPTION (STATIC_BUILD_WITH_DYNAMIC_STDLIB "Build a (mostly) statically linked release binary. \
57+
Glibc and C++ standard library is linked dynamically." OFF)
58+
59+
if (STATIC_BUILD_WITH_DYNAMIC_GLIBC OR STATIC_BUILD_WITH_DYNAMIC_STDLIB)
5560
# We want to optimize the binary size for a static release binary by default.
5661
set (_ENABLE_LTO_DEFAULT ON)
5762
else()
@@ -130,9 +135,15 @@ endif ()
130135
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
131136

132137
# Set the required options for a (mostly) static release build.
133-
if(BUILD_STATIC_RELEASE_SANS_GLIBC)
138+
if(STATIC_BUILD_WITH_DYNAMIC_GLIBC OR STATIC_BUILD_WITH_DYNAMIC_STDLIB)
139+
if (STATIC_BUILD_WITH_DYNAMIC_GLIBC AND STATIC_BUILD_WITH_DYNAMIC_STDLIB)
140+
message(WARNING "Both STATIC_BUILD_WITH_DYNAMIC_GLIBC and STATIC_BUILD_WITH_DYNAMIC_STDLIB "
141+
"enabled at once; using 'DYNAMIC_STDLIB' settings (dynamic glibc and c++ standard library).")
142+
endif()
134143
message(STATUS "Building static release binaries")
135-
message(WARNING "glibc is linked dynamically in current static builds.")
144+
if (NOT STATIC_BUILD_WITH_DYNAMIC_STDLIB)
145+
message(WARNING "glibc is linked dynamically in current static builds.")
146+
endif()
136147
set(BUILD_SHARED_LIBS OFF)
137148
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
138149
# Link Boost statically
@@ -146,8 +157,11 @@ if(BUILD_STATIC_RELEASE_SANS_GLIBC)
146157
# and see whether static linking improves on Linux.
147158
# Do not bring in dynamic libstdcc and libgcc
148159
set(CMAKE_EXE_LINKER_FLAGS
149-
"${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++ -Wl,-z,muldefs"
160+
"${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -Wl,-z,muldefs"
150161
)
162+
if (NOT STATIC_BUILD_WITH_DYNAMIC_STDLIB)
163+
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++")
164+
endif()
151165
add_definitions(-DP4C_STATIC_BUILD)
152166
endif()
153167

Dockerfile

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ ARG CMAKE_UNITY_BUILD=ON
1818
# Whether to enable translation validation
1919
ARG VALIDATION=OFF
2020
# This creates a release build that includes link time optimization and links
21-
# all libraries statically.
22-
ARG BUILD_STATIC_RELEASE_SANS_GLIBC=OFF
21+
# all libraries except for glibc statically.
22+
ARG STATIC_BUILD_WITH_DYNAMIC_GLIBC=OFF
23+
# This creates a release build that includes link time optimization and links
24+
# all libraries except for glibc and libstdc++ statically.
25+
ARG STATIC_BUILD_WITH_DYNAMIC_STDLIB=OFF
2326
# No questions asked during package installation.
2427
ARG DEBIAN_FRONTEND=noninteractive
2528
# Whether to install dependencies required to run PTF-ebpf tests

tools/ci-build.sh

+7-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ P4C_DIR=$(readlink -f ${THIS_DIR}/..)
2222
# Whether to enable translation validation
2323
: "${VALIDATION:=OFF}"
2424
# This creates a release build that includes link time optimization and links
25-
# all libraries statically.
26-
: "${BUILD_STATIC_RELEASE_SANS_GLIBC:=OFF}"
25+
# all libraries except for glibc statically.
26+
: "${STATIC_BUILD_WITH_DYNAMIC_GLIBC:=OFF}"
27+
# This creates a release build that includes link time optimization and links
28+
# all libraries except for glibc and libstdc++ statically.
29+
: "${STATIC_BUILD_WITH_DYNAMIC_STDLIB:=OFF}"
2730
# No questions asked during package installation.
2831
: "${DEBIAN_FRONTEND:=noninteractive}"
2932
# Whether to install dependencies required to run PTF-ebpf tests
@@ -236,7 +239,8 @@ export CXXFLAGS="${CXXFLAGS} -O3"
236239
# Toggle unity compilation.
237240
CMAKE_FLAGS+="-DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD} "
238241
# Toggle static builds.
239-
CMAKE_FLAGS+="-DBUILD_STATIC_RELEASE_SANS_GLIBC=${BUILD_STATIC_RELEASE_SANS_GLIBC} "
242+
CMAKE_FLAGS+="-DSTATIC_BUILD_WITH_DYNAMIC_GLIBC=${STATIC_BUILD_WITH_DYNAMIC_GLIBC} "
243+
CMAKE_FLAGS+="-DSTATIC_BUILD_WITH_DYNAMIC_STDLIB=${STATIC_BUILD_WITH_DYNAMIC_STDLIB} "
240244
# Toggle the installation of the tools back end.
241245
CMAKE_FLAGS+="-DENABLE_TEST_TOOLS=${ENABLE_TEST_TOOLS} "
242246
# RELEASE should be default, but we want to make sure.

tools/ci-check-static.sh

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
3+
# Script for checking semi-static build results.
4+
5+
# No set -e. Do not exit on error, errors are handled explictly.
6+
set -x # Make command execution verbose
7+
set -u # Error on unbound variables.
8+
9+
# Usage: check EXPECTED REAL_RET_CODE BINARY MESSAGE
10+
check() {
11+
if [[ $2 = 0 ]]; then
12+
expected='true';
13+
else
14+
expected='false';
15+
fi
16+
if [[ $1 != $expected ]]; then
17+
echo "Binary dynamic dependency check failed for ${3}: ${4}."
18+
ldd $3
19+
exit 1
20+
fi
21+
}
22+
23+
# Usage: has_lib EXPECTED BINARY LIB_PATTERN
24+
# Does string match, not regex match.
25+
has_lib() {
26+
ldd $2 2>&1 | grep -F -qi $3
27+
check $1 $? $2 "has_lib ${3} expected to be ${1}"
28+
}
29+
30+
# Usage: is_static EXPECTED BINARY
31+
is_static() {
32+
ldd $2 2>&1 | grep -E -qi "(not a dynamic executable)|(statically linked)"
33+
check $1 $? $2 "is_static expected to be ${1}"
34+
}
35+
36+
# The binaries to check -- arguments except for $0.
37+
bins=${@:1}
38+
39+
# Run checks on all the binaries produced by the builds.
40+
for bin in ${bins[@]}; do
41+
# Disabling this checks until we find a better way to build a fully static binary.
42+
# is_static true $bin
43+
is_static false $bin
44+
has_lib true $bin "libc"
45+
has_lib false $bin "libboost_iostreams"
46+
if [[ ${STATIC_BUILD_WITH_DYNAMIC_STDLIB} = "ON" ]]; then
47+
has_lib true $bin 'libstdc++'
48+
else
49+
has_lib false $bin 'libstdc++'
50+
fi
51+
done

tools/debian-build/packaging.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ CONFOPT+="-DCMAKE_UNITY_BUILD=ON "
1414
# RELEASE should be default, but we want to make sure.
1515
CONFOPT+="-DCMAKE_BUILD_TYPE=RELEASE "
1616
# The binaries we produce should not depend on system libraries.
17-
CONFOPT+="-DBUILD_STATIC_RELEASE_SANS_GLIBC=ON "
17+
CONFOPT+="-DSTATIC_BUILD_WITH_DYNAMIC_GLIBC=ON "
1818
MAKE_DIST="cd ${P4C_DIR}/backends/ebpf && ./build_libbpf && mkdir -p ${P4C_DIR}/build && cd ${P4C_DIR}/build && cmake .. $CONFOPT && make && make dist"
1919
# Distributions which are *not* supported!
2020
NOT_TARGET_DISTRIBUTIONS="lucid precise trusty xenial bionic"

0 commit comments

Comments
 (0)