@@ -28,6 +28,17 @@ DOCKER_TMPL:=$(CB_DIR)/m4/Dockerfile.m4
2828# List of all the docker images (sorted for "crossbuild.info")
2929CB_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)
3243GITDIR: =$(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#
118152crossbuild.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
268465endif
0 commit comments