Skip to content

Commit d52c1e3

Browse files
committed
Rework build script; add support for macOS
1 parent 1cc10ea commit d52c1e3

File tree

6 files changed

+228
-66
lines changed

6 files changed

+228
-66
lines changed

.dockerignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
workspace/
2+
workspace-linux/
3+
workspace-mac/
4+
ws/

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.DS_Store
2+
workspace/
3+
workspace-linux/
4+
workspace-mac/
5+
ws/
6+
install-build-deps.sh
7+
courgette.log

Dockerfile

+10-29
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,27 @@
11
# Dockerfile for a container capable of building the Courgette target of
2-
# Chromium.
3-
#
4-
# https://chromium.googlesource.com/chromium/src/+/master/docs/linux_build_instructions.md
2+
# Chromium for Linux.
53

64
FROM ubuntu:trusty
75

86
WORKDIR /root
9-
VOLUME /root/out
107

118
# Install bootstrap dependencies
129
RUN apt-get update && apt-get install -y \
1310
curl \
1411
git \
1512
python
1613

17-
# Install depot_tools
18-
RUN git clone --depth 1 \
19-
https://chromium.googlesource.com/chromium/tools/depot_tools.git
20-
ENV PATH=$PATH:/root/depot_tools
21-
22-
# Get the code
23-
WORKDIR chromium
24-
RUN fetch --nohooks --no-history chromium
25-
26-
# Install additional build dependencies
27-
WORKDIR src
28-
RUN ./build/install-build-deps.sh \
14+
# Install the build dependencies
15+
COPY install-build-deps.sh .
16+
RUN ./install-build-deps.sh \
2917
--no-arm --no-chromeos-fonts --no-nacl \
3018
--no-prompt
3119

32-
# Run the hooks
33-
RUN gclient runhooks
34-
35-
# Configure the build
36-
RUN mkdir -p out/Default \
37-
&& (echo "enable_nacl = false"; echo "symbol_level = 0") \
38-
>> out/Default/args.gn \
39-
&& gn gen out/Default
40-
41-
# Copy in the build script
42-
WORKDIR /root
20+
# Copy in the build script and packaging materials
4321
COPY build.sh .
44-
COPY packaging courgette
22+
COPY deb-package ./deb-package
4523
RUN chmod +x build.sh
46-
CMD ["/root/build.sh"]
24+
25+
# Set the container command to run the build script
26+
VOLUME /ws
27+
CMD ["/root/build.sh", "/ws", "no-update"]

README.md

+52-12
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,62 @@ Courgette lives inside the Chromium repository and must be compiled using the
99
complex Chromium build system. It is not offered as an official standalone
1010
installable package.
1111

12-
This repository describes a Docker container that builds Courgette for Linux
13-
x86_64.
12+
This repository contains a build script that automates the process of compiling
13+
Courgette.
1414

15+
Prebuilt packages may be found on the [release page][releases], but these are
16+
not kept up to date.
17+
18+
[releases]: https://github.com/rgov/courgette-build/releases
19+
20+
21+
## Debian and macOS
22+
23+
Please follow the [platform-specific guides][guides] on building Chromium to
24+
install the initial dependencies such as `git`.
25+
26+
[guides]: https://www.chromium.org/developers/how-tos/get-the-code
27+
28+
The build script handles the rest:
29+
30+
./build.sh ./workspace
31+
32+
This produces a binary at `./workspace/chromium/src/out/Default/courgette`.
33+
34+
It also produces a Debian package at
35+
`./workspace/courgette-linux_{version}-{date}+{revision}_{arch}.deb` for Linux
36+
builds, or a similarly-named zip archive for macOS builds.
37+
38+
Use `ldd` (Linux) or `otool -L` (macOS) to view which shared libraries that
39+
Courgette links against, such as `libbase` and `libc++`.
40+
41+
42+
## Debian, using a Docker container
43+
44+
You can construct a Docker container with all of the build dependencies ready
45+
to go:
46+
47+
./build.sh ./workspace fetch-only
48+
cp ./workspace/chromium/src/build/install-build-deps.sh .
1549
docker build -t courgette-build .
16-
docker run -v "$(pwd):/root/out" courgette-build
1750

18-
Each time the `docker run` command is executed, the latest Chromium sources are
19-
fetched and built, and `courgette-{version}.deb` is created in the current
20-
directory.
51+
To execute a build inside the container, run:
2152

22-
The Docker container image is very large, so when no longer needed, it can be
23-
deleted with:
53+
docker run -v "$(pwd)/workspace:/ws" courgette-build
2454

25-
docker rmi courgette-build
55+
### macOS host notes
2656

27-
Prebuilt packages may be found on the [release page][releases], but these are
28-
not kept up to date.
57+
- Docker makes a copy of the entire directory while building a container
58+
image. The `.dockerignore` file is configured to exclude `./workspace`, as
59+
a checkout of Chromium sources can easily exceed 10GB. If you use another
60+
workspace name, it is strongly advised to place it outside of this
61+
directory.
2962

30-
[releases]: https://github.com/rgov/courgette-build/releases
63+
- Using the same workspace for macOS and Docker-based Debian builds is
64+
currently not possible. It *may* be possible to clone a workspace created
65+
with the `fetch-only` option before any further steps have been applied:
66+
67+
```
68+
./build.sh ./workspace fetch-only
69+
cp -ca workspace workspace-linux
70+
```

build.sh

+153-23
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,161 @@
1-
#!/bin/sh -e
1+
#!/bin/bash -e
22

3-
# This is the second half of the process of building Courgette; the Dockerfile
4-
# sets up the environment and configures the build. Now we need to actually
5-
# perform the build and package the results.
3+
# This script builds the Courgette target from Chromium. It works on macOS and
4+
# Linux. Please see the accompanying README.md file.
65
#
7-
# https://chromium.googlesource.com/chromium/src/+/master/docs/linux_build_instructions.md
6+
# https://www.chromium.org/developers/how-tos/get-the-code
87

9-
cd /root/chromium/src
10-
GITHASH=$(git rev-parse --short HEAD)
8+
function status {
9+
printf '\E[33m'
10+
echo "$@"
11+
printf '\E[0m'
12+
}
13+
14+
if [ "$#" -eq 0 ]; then
15+
echo "Usage: $0 workspace-dir [fetch-only|no-update]" >&2
16+
exit 1
17+
fi
18+
19+
# Enter the workspace
20+
mkdir -p "$1"
21+
cd "$1"
22+
23+
# Install depot_tools
24+
if [ ! -d depot_tools ]; then
25+
status "[*] Cloning depot_tools"
26+
git clone --depth 1 \
27+
https://chromium.googlesource.com/chromium/tools/depot_tools.git
28+
elif [ "$2" != "no-update" ]; then
29+
status "[*] Updating depot_tools"
30+
pushd depot_tools
31+
git pull
32+
popd
33+
fi
34+
35+
export PATH="$(pwd)/depot_tools:${PATH}"
36+
37+
# Is this our first build?
38+
if [ ! -f .first-build-finished ]; then
39+
FIRST_BUILD=1
40+
else
41+
FIRST_BUILD=0
42+
fi
43+
44+
# Get the code
45+
if [ ! -d chromium/src ]; then
46+
status "[*] Fetching Chromium sources"
47+
mkdir -p chromium
48+
pushd chromium
49+
git config --global core.precomposeUnicode true
50+
fetch --nohooks --no-history chromium
51+
popd
52+
elif [ "$2" != "no-update" ]; then
53+
status "[*] Updating Chromium sources"
54+
pushd chromium/src
55+
git rebase-update
56+
popd
57+
fi
1158

12-
# Update the checkout and re-sync dependencies and hooks
13-
git rebase-update
14-
gclient sync
59+
# Stop here if we just wanted to fetch the code
60+
if [ "$2" = "fetch-only" ]; then
61+
exit 0
62+
fi
63+
64+
# Install additional build dependencies
65+
if [ $FIRST_BUILD -eq 1 ] && [ "$(uname -s)" = "Linux" ]; then
66+
status "[*] Installing build dependencies"
67+
pushd chromium/src
68+
./build/install-build-deps.sh \
69+
--no-arm --no-chromeos-fonts --no-nacl \
70+
--no-prompt
71+
popd
72+
fi
73+
74+
# Run the hooks
75+
pushd chromium/src
76+
if [ $FIRST_BUILD -eq 1 ]; then
77+
status "[*] Running hooks"
78+
gclient runhooks
79+
elif [ "$2" != "no-update" ]; then
80+
status "[*] Running hooks"
81+
gclient sync
82+
fi
83+
popd
84+
85+
# Configure the build
86+
if [ ! -d chromium/src/out/Default ]; then
87+
status "[*] Configuring"
88+
pushd chromium/src
89+
mkdir -p out/Default
90+
(echo "enable_nacl = false"; echo "symbol_level = 0") > out/Default/args.gn
91+
gn gen out/Default
92+
popd
93+
fi
1594

1695
# Build Courgette
96+
status "[*] Building Courgette"
97+
pushd chromium/src
1798
autoninja -C out/Default courgette
99+
popd
100+
touch .first-build-finished
101+
102+
# Create the version string
103+
pushd chromium/src
104+
DATE=$(date +"%Y%m%d")
105+
GITHASH=$(git rev-parse --short HEAD)
106+
VERSION="1.0.0-${DATE}+${GITHASH}"
107+
popd
108+
109+
# Build the Debian package on Linux
110+
if [ "$(uname -s)" = "Linux" ]; then
111+
status "[*] Creating Debian package"
112+
113+
# Copy the packaging template into the workspace
114+
rm -rf courgette
115+
cp -r "$(dirname "$0")"/deb-package courgette
116+
117+
# Copy the Courgette binary into the package
118+
mkdir -p courgette/usr/bin
119+
cp chromium/src/out/Default/courgette courgette/usr/bin
120+
121+
# Copy all built libraries it depends on in as well
122+
mkdir -p courgette/usr/lib
123+
LIBDEPS=$(ldd chromium/src/out/Default/courgette \
124+
| grep 'chromium' \
125+
| awk '{ print $3 }')
126+
cp $LIBDEPS courgette/usr/lib
127+
128+
# Patch up the control file
129+
ARCH=$(dpkg --print-architecture)
130+
sed -i \
131+
-e "s/@VERSION@/$VERSION/g" \
132+
-e "s/@ARCH@/$ARCH/g" \
133+
courgette/DEBIAN/control
134+
135+
# Build the package
136+
dpkg-deb --build courgette
137+
mv courgette.deb "courgette-linux_${VERSION}_${ARCH}.deb"
138+
rm -rf courgette
139+
fi
18140

19-
# Build the Debian package
20-
mkdir -p /root/courgette/usr/bin /root/courgette/usr/lib
21-
cp out/Default/courgette /root/courgette/usr/bin
22-
cp $(ldd out/Default/courgette | grep '/root' | awk '{ print $3 }') \
23-
/root/courgette/usr/lib
24-
sed -i "s/@GITHASH@/$GITHASH/g" \
25-
/root/courgette/DEBIAN/control
26-
dpkg-deb --build /root/courgette
27-
mv /root/courgette.deb /root/out/courgette-${GITHASH}.deb
28-
29-
# Install the Debian package and test it
30-
dpkg -i /root/out/courgette-*.deb
31-
courgette --help 2>&1 | grep -q 'genbsdiff'
141+
# Build a zip archive on macOS
142+
if [ "$(uname -s)" = "Darwin" ]; then
143+
status "[*] Creating archive"
144+
145+
# Create the archive directory
146+
rm -rf courgette
147+
mkdir courgette
148+
149+
# Copy the courgette binary into the directory
150+
cp chromium/src/out/Default/courgette courgette
151+
LIBDEPS=$(otool -L chromium/src/out/Default/courgette \
152+
| grep '@rpath' \
153+
| awk '{ print $1 }' \
154+
| sed 's,@rpath/,chromium/src/out/Default/,g')
155+
cp $LIBDEPS courgette
156+
157+
# Make the zip archive
158+
ARCH=$(uname -m)
159+
zip -r "courgette-mac_${VERSION}_${ARCH}.zip" courgette
160+
rm -rf courgette
161+
fi
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: courgette
2-
Version: 1.0.0-@GITHASH@
3-
Architecture: amd64
2+
Version: @VERSION@
3+
Architecture: @ARCH@
44
Maintainer: "Ryan Govostes" <rgovostes@gmail.com>
55
Description: Courgette binary patching tool

0 commit comments

Comments
 (0)