Skip to content

Commit 31ffadb

Browse files
committed
WIP: crossbuild profiling images now supported by Makefile targets, including regenerating from the .m4 template file.
1 parent 35dd73f commit 31ffadb

4 files changed

Lines changed: 251 additions & 34 deletions

File tree

scripts/docker/crossbuild.mk

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ DOCKER_TMPL:=$(CB_DIR)/m4/Dockerfile.m4
2828
# List of all the docker images (sorted for "crossbuild.info")
2929
CB_IMAGES:=$(sort $(patsubst $(DT)/%,%,$(wildcard $(DT)/*)))
3030

31+
# Where the profiling docker directories are
32+
PT:=$(CB_DIR)/profiling
33+
34+
# Docker image and container name prefixes for profiling builds
35+
CB_PROF_IPREFIX:=freeradius40x-prof
36+
CB_PROF_CPREFIX:=fr40x-prof-
37+
38+
# List of profiling images (only directories that contain a Dockerfile.cb)
39+
CB_PROF_IMAGES:=$(sort $(patsubst $(PT)/%/Dockerfile.cb,%,$(wildcard $(PT)/*/Dockerfile.cb)))
40+
41+
3142
# Location of the .git dir (may be different for e.g. submodules)
3243
GITDIR:=$(shell perl -MCwd -e 'print Cwd::abs_path shift' $$(git rev-parse --git-dir))
3344

@@ -78,6 +89,7 @@ crossbuild.help: crossbuild.info
7889
@echo " crossbuild.reset - remove cache of docker state"
7990
@echo " crossbuild.clean - down and reset all targets"
8091
@echo " crossbuild.wipe - destroy all crossbuild Docker images"
92+
@echo " crossbuild.regen - regenerate all Dockerfiles from m4 templates"
8193
@echo ""
8294
@echo "Per-image targets:"
8395
@echo " crossbuild.IMAGE - build and test image <IMAGE>"
@@ -89,6 +101,28 @@ crossbuild.help: crossbuild.info
89101
@echo " crossbuild.IMAGE.reset - remove cache of docker state"
90102
@echo " crossbuild.IMAGE.clean - stop container and tidy up"
91103
@echo " crossbuild.IMAGE.wipe - remove Docker image"
104+
@echo " crossbuild.IMAGE.regen - regenerate Dockerfile from m4 template"
105+
@echo ""
106+
@echo "Profiling targets (use scripts/docker/profiling/* Dockerfiles):"
107+
@echo " crossbuild.prof - build and test all profiling images"
108+
@echo " crossbuild.prof.info - list profiling images"
109+
@echo " crossbuild.prof.down - stop all profiling containers"
110+
@echo " crossbuild.prof.reset - remove cache of docker state (profiling)"
111+
@echo " crossbuild.prof.clean - down and reset all profiling targets"
112+
@echo " crossbuild.prof.wipe - destroy all profiling Docker images"
113+
@echo " crossbuild.prof.regen - regenerate all profiling Dockerfiles from m4 templates"
114+
@echo ""
115+
@echo "Per-image profiling targets:"
116+
@echo " crossbuild.IMAGE.prof - build and test profiling image <IMAGE>"
117+
@echo " crossbuild.IMAGE.prof.log - show latest build log"
118+
@echo " crossbuild.IMAGE.prof.up - start profiling container"
119+
@echo " crossbuild.IMAGE.prof.down - stop profiling container"
120+
@echo " crossbuild.IMAGE.prof.sh - shell in profiling container"
121+
@echo " crossbuild.IMAGE.prof.refresh - push latest commits into container"
122+
@echo " crossbuild.IMAGE.prof.reset - remove cache of docker state"
123+
@echo " crossbuild.IMAGE.prof.clean - stop container and tidy up"
124+
@echo " crossbuild.IMAGE.prof.wipe - remove Docker image"
125+
@echo " crossbuild.IMAGE.prof.regen - regenerate profiling Dockerfile from m4 template"
92126
@echo ""
93127
@echo "Use 'make NOCACHE=1 ...' to disregard the Docker cache on build"
94128

@@ -117,6 +151,24 @@ crossbuild.wipe: $(foreach IMG,${CB_IMAGES},crossbuild.${IMG}.wipe)
117151
#
118152
crossbuild.regen: $(foreach IMG,${CB_IMAGES},crossbuild.${IMG}.regen)
119153

154+
#
155+
# Profiling top-level targets
156+
#
157+
.PHONY: crossbuild.prof
158+
crossbuild.prof: crossbuild.prof.info $(foreach IMG,${CB_PROF_IMAGES},crossbuild.${IMG}.prof)
159+
160+
.PHONY: crossbuild.prof.info crossbuild.prof.info_header
161+
crossbuild.prof.info: crossbuild.prof.info_header $(foreach IMG,${CB_PROF_IMAGES},crossbuild.${IMG}.prof.status)
162+
163+
crossbuild.prof.info_header:
164+
@echo Profiling Images:
165+
166+
crossbuild.prof.reset: $(foreach IMG,${CB_PROF_IMAGES},crossbuild.${IMG}.prof.reset)
167+
crossbuild.prof.down: $(foreach IMG,${CB_PROF_IMAGES},crossbuild.${IMG}.prof.down)
168+
crossbuild.prof.clean: $(foreach IMG,${CB_PROF_IMAGES},crossbuild.${IMG}.prof.clean)
169+
crossbuild.prof.wipe: $(foreach IMG,${CB_PROF_IMAGES},crossbuild.${IMG}.prof.wipe)
170+
crossbuild.prof.regen: $(foreach IMG,${CB_PROF_IMAGES},crossbuild.${IMG}.prof.regen)
171+
120172

121173
#
122174
# Define rules for building a particular image
@@ -264,5 +316,150 @@ $(foreach IMAGE,$(CB_IMAGES),\
264316
$(eval $(call CROSSBUILD_IMAGE_RULE,$(IMAGE))))
265317

266318

319+
#
320+
# Define rules for building a particular profiling image.
321+
# Uses scripts/docker/profiling/IMAGE/Dockerfile.cb instead of
322+
# scripts/docker/build/IMAGE/Dockerfile.cb. Stamp files and log
323+
# files get a "-prof" suffix to avoid collisions with regular builds.
324+
#
325+
define CROSSBUILD_PROF_IMAGE_RULE
326+
327+
#
328+
# Show status (based on stamp files)
329+
#
330+
.PHONY: crossbuild.${1}.prof.status
331+
crossbuild.${1}.prof.status:
332+
${Q}printf "%s" "`echo \" ${1} \" | cut -c 1-20`"
333+
${Q}if [ -e "$(DD)/stamp-up.${1}-prof" ]; then echo "running"; \
334+
elif [ -e "$(DD)/stamp-image.${1}-prof" ]; then echo "built"; \
335+
else echo "-"; fi
336+
337+
#
338+
# Build the docker image from the profiling Dockerfile.cb
339+
#
340+
$(DD)/stamp-image.${1}-prof:
341+
${Q}echo "BUILD ${1} ($(CB_PROF_IPREFIX)/${1}) > $(DD)/build.${1}-prof"
342+
${Q}echo " Dockerfile: $(PT)/${1}/Dockerfile.cb"
343+
${Q}docker build $(DOCKER_BUILD_OPTS) $(PT)/${1} -f $(PT)/${1}/Dockerfile.cb -t $(CB_PROF_IPREFIX)/${1} >$(DD)/build.${1}-prof 2>&1
344+
${Q}touch $(DD)/stamp-image.${1}-prof
345+
346+
#
347+
# Start up the docker container
348+
#
349+
.PHONY: $(DD)/docker.up.${1}-prof
350+
$(DD)/docker.up.${1}-prof: $(DD)/stamp-image.${1}-prof
351+
${Q}echo "START ${1} ($(CB_PROF_CPREFIX)${1})"
352+
${Q}docker container inspect $(CB_PROF_CPREFIX)${1} >/dev/null 2>&1 || \
353+
docker run -d --rm \
354+
--privileged --cap-add=ALL \
355+
--mount=type=bind,source="$(GITDIR)",destination=/srv/src,ro \
356+
--name $(CB_PROF_CPREFIX)${1} $(CB_PROF_IPREFIX)/${1} \
357+
/bin/sh -c 'while true; do sleep 60; done' >/dev/null
358+
359+
$(DD)/stamp-up.${1}-prof: $(DD)/docker.up.${1}-prof
360+
${Q}touch $(DD)/stamp-up.${1}-prof
361+
362+
.PHONY: crossbuild.${1}.prof.up
363+
crossbuild.${1}.prof.up: $(DD)/stamp-up.${1}-prof
364+
365+
#
366+
# Refresh and run tests in the container
367+
#
368+
.PHONY: $(DD)/docker.refresh.${1}-prof
369+
$(DD)/docker.refresh.${1}-prof: $(DD)/stamp-up.${1}-prof
370+
${Q}echo "REFRESH ${1}"
371+
${Q}docker container exec $(CB_PROF_CPREFIX)${1} sh -lc 'rsync -a /srv/src/ /srv/local-src/'
372+
${Q}docker container exec $(CB_PROF_CPREFIX)${1} sh -lc 'git config -f /srv/local-src/config core.bare true'
373+
${Q}docker container exec $(CB_PROF_CPREFIX)${1} sh -lc 'git config -f /srv/local-src/config --unset core.worktree || true'
374+
${Q}docker container exec $(CB_PROF_CPREFIX)${1} sh -lc 'git config --global --add safe.directory /srv/local-src'
375+
${Q}docker container exec $(CB_PROF_CPREFIX)${1} sh -lc '[ -d /srv/build ] || git clone /srv/local-src /srv/build'
376+
${Q}docker container exec $(CB_PROF_CPREFIX)${1} sh -lc '(cd /srv/build && git pull --rebase)'
377+
${Q}docker container exec $(CB_PROF_CPREFIX)${1} sh -lc '[ -e /srv/build/config.log ] || echo CONFIGURE ${1}'
378+
${Q}docker container exec $(CB_PROF_CPREFIX)${1} sh -lc '[ -e /srv/build/config.log ] || (cd /srv/build && ./configure -C)' > $(DD)/configure.${1}-prof 2>&1
379+
380+
.PHONY: $(DD)/docker.run.${1}-prof
381+
$(DD)/docker.run.${1}-prof: $(DD)/docker.refresh.${1}-prof
382+
${Q}echo "TEST ${1} > $(DD)/log.${1}-prof"
383+
${Q}docker container exec $(CB_PROF_CPREFIX)${1} sh -lc '(cd /srv/build && make && make test)' > $(DD)/log.${1}-prof 2>&1 || ( echo FAIL ${1} && false )
384+
385+
#
386+
# Stop the docker container
387+
#
388+
.PHONY: crossbuild.${1}.prof.down
389+
crossbuild.${1}.prof.down:
390+
@echo STOP ${1}
391+
${Q}docker container kill $(CB_PROF_CPREFIX)${1} || true
392+
@rm -f $(DD)/stamp-up.${1}-prof
393+
394+
.PHONY: crossbuild.${1}.prof.clean
395+
crossbuild.${1}.prof.clean: crossbuild.${1}.prof.down crossbuild.${1}.prof.reset
396+
397+
#
398+
# Shell into container
399+
#
400+
.PHONY: crossbuild.${1}.prof.sh
401+
crossbuild.${1}.prof.sh: crossbuild.${1}.prof.up
402+
${Q}docker exec -it $(CB_PROF_CPREFIX)${1} sh -c 'cd / ; cd /srv/build 2>/dev/null; bash' || true
403+
404+
#
405+
# Show last build logs
406+
#
407+
.PHONY: crossbuild.${1}.prof.log
408+
crossbuild.${1}.prof.log:
409+
@if which less >/dev/null; then \
410+
less +G $(DD)/log.${1}-prof;\
411+
elif which more >/dev/null; then \
412+
more $(DD)/log.${1}-prof;\
413+
else cat $(DD)/log.${1}-prof; fi
414+
415+
#
416+
# Tidy up stamp files
417+
#
418+
.PHONY: crossbuild.${1}.prof.reset
419+
crossbuild.${1}.prof.reset:
420+
${Q}echo RESET ${1}
421+
${Q}rm -f $(DD)/stamp-up.${1}-prof
422+
${Q}rm -f $(DD)/stamp-image.${1}-prof
423+
424+
#
425+
# Remove Docker image
426+
#
427+
.PHONY: crossbuild.${1}.prof.wipe
428+
crossbuild.${1}.prof.wipe:
429+
${Q}echo CLEAN ${1}
430+
${Q}docker image rm $(CB_PROF_IPREFIX)/${1} >/dev/null 2>&1 || true
431+
${Q}rm -f $(DD)/stamp-image.${1}-prof
432+
433+
#
434+
# Refresh git repository within the docker container
435+
#
436+
.PHONY: crossbuild.${1}.prof.refresh
437+
crossbuild.${1}.prof.refresh: $(DD)/docker.refresh.${1}-prof
438+
439+
#
440+
# Regenerate the profiling Dockerfile.cb from the m4 templates
441+
#
442+
.PHONY: crossbuild.${1}.prof.regen
443+
crossbuild.${1}.prof.regen: $(PT)/${1}/Dockerfile.cb
444+
445+
$(PT)/${1}/Dockerfile.cb: $(DOCKER_TMPL) $(CB_DIR)/m4/crossbuild.deb.m4 $(CB_DIR)/m4/crossbuild.rpm.m4
446+
${Q}echo REGEN ${1}
447+
${Q}m4 -I $(CB_DIR)/m4 -D D_NAME=${1} -D D_TYPE=profiling $$< > $$@
448+
449+
#
450+
# Run the build test
451+
#
452+
.PHONY: crossbuild.${1}.prof
453+
crossbuild.${1}.prof: $(DD)/docker.run.${1}-prof
454+
455+
endef
456+
457+
#
458+
# Add all the profiling image building rules
459+
#
460+
$(foreach IMAGE,$(CB_PROF_IMAGES),\
461+
$(eval $(call CROSSBUILD_PROF_IMAGE_RULE,$(IMAGE))))
462+
463+
267464
# if docker is defined
268465
endif

scripts/docker/m4/Dockerfile.m4

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ ifelse(
2626
D_NAME, [debiansid], [p_SET([deb], [debian], [99], [sid], [debian:sid])],
2727
D_NAME, [ubuntu22], [p_SET([deb], [ubuntu], [22], [jammy], [ubuntu:22.04])],
2828
D_NAME, [ubuntu24], [p_SET([deb], [ubuntu], [24], [noble], [ubuntu:24.04])],
29-
D_NAME, [ubuntu24-prof], [p_SET([deb], [ubuntu], [24], [noble], [ubuntu:24.04])],
3029
D_NAME, [rocky9], [p_SET([rpm], [rocky], [9], [9], [rockylinux/rockylinux:9])],
3130
D_NAME, [rocky10], [p_SET([rpm], [rocky], [10], [10], [rockylinux/rockylinux:10])],
3231
[errprint(error: OS 'D_NAME' not defined[,] see __file__
@@ -35,9 +34,9 @@ ifelse(
3534
undefine([p_SET])
3635
divert[]dnl
3736
[#] Auto generated for D_NAME
38-
[#] from scripts/docker/m4/D_TYPE.PKG_TYPE.m4
37+
[#] from scripts/docker/m4/ifelse(D_TYPE, [profiling], [crossbuild], D_TYPE).PKG_TYPE.m4
3938
[#]
40-
[#] Rebuild this file with `make D_TYPE.D_NAME.regen`
39+
[#] Rebuild this file with `make ifelse(D_TYPE, [profiling], [crossbuild.]D_NAME[.prof.regen], D_TYPE[.]D_NAME[.regen])`
4140
[#]
4241
changequote([`], ['])dnl
43-
include(D_TYPE.PKG_TYPE.m4)dnl
42+
include(ifelse(D_TYPE, `profiling', `crossbuild', D_TYPE).PKG_TYPE.m4)dnl

scripts/docker/m4/crossbuild.deb.m4

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,25 @@ dnl for tests:
9494
oathtool
9595

9696

97+
ifelse(D_TYPE, `profiling', `
98+
#
99+
# Install profiling tools
100+
#
101+
RUN apt-get install $APT_OPTS \
102+
libgoogle-perftools-dev \
103+
google-perftools \
104+
valgrind \
105+
heaptrack \
106+
psmisc \
107+
kcachegrind \
108+
kio \
109+
libkf5iconthemes5 \
110+
libkf5parts5 \
111+
libkf5textwidgets5 \
112+
libqt5gui5 \
113+
libqt5widgets5
114+
')dnl
115+
97116
#
98117
# Setup a src dir in /usr/local
99118
#

scripts/docker/profiling/ubuntu24/Dockerfile.cb

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Auto generated for ubuntu24
2+
# from scripts/docker/m4/crossbuild.deb.m4
3+
#
4+
# Rebuild this file with `make crossbuild.ubuntu24.prof.regen`
5+
#
16
ARG from=ubuntu:24.04
27
FROM ${from} AS build
38

@@ -7,44 +12,16 @@ ARG APT_OPTS="-y --option=Dpkg::options::=--force-unsafe-io --no-install-recomme
712

813
ARG DEBIAN_FRONTEND=noninteractive
914

15+
1016
#
1117
# Install add-apt-repository (may be needed for clang) and
1218
# package development utilities
1319
#
1420
RUN apt-get update && \
1521
apt-get install $APT_OPTS \
16-
# Build essentials
17-
build-essential \
18-
cmake \
19-
make \
20-
git \
21-
vim \
22-
# SSL / compression / memory libs
23-
libssl-dev \
24-
libbrotli-dev \
25-
libtalloc-dev \
26-
# Google perf tools
27-
libgoogle-perftools-dev \
28-
google-perftools \
29-
# Valgrind / heap profiling
30-
valgrind \
31-
heaptrack \
32-
# Utilities
33-
less \
34-
psmisc \
35-
# kcachegrind - GUI callgrind viewer (requires display/X11 forwarding or VNC)
36-
# Pulls in heavy KDE/Qt dependencies (~200MB+).
37-
# To use: run with `docker run -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix`
38-
kcachegrind \
39-
kio \
40-
libkf5iconthemes5 \
41-
libkf5parts5 \
42-
libkf5textwidgets5 \
43-
libqt5gui5 \
44-
libqt5widgets5 \
45-
# Original build dependencies from the old Dockerfile, may be needed for some build steps
4622
devscripts \
4723
equivs \
24+
git \
4825
gnupg2 \
4926
lsb-release \
5027
procps \
@@ -54,6 +31,7 @@ RUN apt-get update && \
5431
apt-get clean && \
5532
rm -r /var/lib/apt/lists/*
5633

34+
5735
#
5836
# Set up NetworkRADIUS extras repository
5937
#
@@ -62,13 +40,18 @@ RUN install -d -o root -g root -m 0755 /etc/apt/keyrings && \
6240
echo "deb [signed-by=/etc/apt/keyrings/packages.networkradius.com.asc] http://packages.networkradius.com/extras/ubuntu/noble noble main" > /etc/apt/sources.list.d/networkradius-extras.list && \
6341
apt-get update
6442

43+
6544
#
6645
# Install compilers
6746
#
6847
RUN apt-get install $APT_OPTS \
6948
g++ \
7049
llvm clang lldb
7150

51+
52+
53+
54+
7255
#
7356
# Install some extra packages
7457
#
@@ -82,12 +65,31 @@ RUN apt-get install $APT_OPTS \
8265
oathtool
8366

8467

68+
69+
#
70+
# Install profiling tools
71+
#
72+
RUN apt-get install $APT_OPTS \
73+
libgoogle-perftools-dev \
74+
google-perftools \
75+
valgrind \
76+
heaptrack \
77+
psmisc \
78+
kcachegrind \
79+
kio \
80+
libkf5iconthemes5 \
81+
libkf5parts5 \
82+
libkf5textwidgets5 \
83+
libqt5gui5 \
84+
libqt5widgets5
85+
8586
#
8687
# Setup a src dir in /usr/local
8788
#
8889
RUN mkdir -p /usr/local/src/repositories
8990
WORKDIR /usr/local/src/repositories
9091

92+
9193
#
9294
# Shallow clone the FreeRADIUS source
9395
#

0 commit comments

Comments
 (0)