Skip to content

Commit 65a4aef

Browse files
committed
tooling: Make cloe a super-build of all packages
New: - Add `cloe-meta` package to replace previous role of `cloe`. - Add `cloe-plugins-core` package recipe (but do not build by default). - Add editable builds to GitHub workflow `build-cloe` matrix. Changed: - Package `cloe` provides all Cloe packages compiled in one go. This is a boon to development, as we make `cloe` editable and only have to work with a single package. It also massively speeds up compilation: - Conan and CMake configuration is only performed once. - All cores can now be utilized much more effectively during the build process. - Do not aggressively lint everything The developer can do this themselves by setting a cmake define: https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_CLANG_TIDY.html - Renamed top-level Make targets: - `status` is now `status-all` - `export` is now `export-all` - `deploy` is now `deploy-all` - `clean` is now `clean-all` - `purge` is now `purge-all` - The following top-level Make targets just refer to `cloe` super-build package: - `package` - `smoketest` - `smoketest-deps` - `status` - `export` Fixed: - Plugin Conan configurations do not export correct library path.
1 parent 906a6a2 commit 65a4aef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1084
-410
lines changed

.github/workflows/build-cloe.yaml

+10-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,16 @@ jobs:
3535
- "cloe-normal"
3636
package_target:
3737
# 1. Build each test configuration in Conan cache and run all tests
38-
- "export export-vendor smoketest-deps smoketest"
38+
- "export-vendor export-all smoketest-deps smoketest"
39+
40+
# 2. Build cloe super-package in editable mode and run tests
41+
- "export-vendor editable all smoketest TEST_CONANFILES=tests/conanfile_superbuild.py"
42+
43+
# 3. TODO: Build individual packages in editable mode and run tests
44+
# This cannot be currently enabled because of a Conan deficiency in v1.
45+
# Once all build tooling is based on Conan v2, we can re-enable this use-case.
46+
# Until then, use the previous target for this use-case.
47+
# - "export-vendor editable-select build-all smoketest TEST_CONANFILES=tests/conanfile_deployment.py"
3948
env:
4049
CONAN_NON_INTERACTIVE: "yes"
4150
DEBIAN_FRONTEND: noninteractive

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ CMakeFiles/
3030
compile_commands.json
3131

3232
# Files generated by Clang:
33+
.cache/
3334
.clangd/
3435
.cache/
3536

CMakeLists.txt

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# This CMakeLists.txt configures a super-build containing everything
2+
# from this repo.
3+
#
4+
# It is currently experimental.
5+
#
6+
7+
cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR)
8+
9+
project(cloe LANGUAGES CXX)
10+
11+
option(CLOE_WITH_ESMINI "Build simulator_esmini plugin?" ON)
12+
option(CLOE_WITH_VTD "Build simulator_vtd plugin?" OFF)
13+
14+
set(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/runtime/cmake")
15+
16+
# Since a super-build does not export packages individually via Conan,
17+
# we cannot depend on Conan-generated CMake config files, instead we
18+
# use the CMake targets directly as if they were already found.
19+
set(CLOE_FIND_PACKAGES OFF CACHE BOOL "Call find_package() for cloe packages" FORCE)
20+
21+
# Ensure output goes to one place so cloe-launch can find the plugins
22+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
23+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
24+
25+
# Ensure we can test from this level.
26+
set(CMAKE_CTEST_ARGUMENTS "--output-on-failure")
27+
include(CTest)
28+
29+
# Order matters:
30+
add_subdirectory(fable)
31+
add_subdirectory(runtime)
32+
add_subdirectory(models)
33+
add_subdirectory(osi)
34+
add_subdirectory(oak)
35+
add_subdirectory(engine)
36+
add_subdirectory(plugins)
37+
38+
if(CLOE_WITH_VTD)
39+
add_subdirectory(optional/vtd)
40+
endif()

Makefile

+84-43
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
# This file contains Makefile targets for the cloe project.
44
#
55

6+
# Make configuration:
7+
SHELL := /bin/bash
8+
GNUMAKEFLAGS := --no-print-directory
9+
SUBMAKEFLAGS :=
10+
611
CLOE_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
712
CLOE_LAUNCH := PYTHONPATH="${CLOE_ROOT}/cli" python3 -m cloe_launch
813

@@ -20,78 +25,98 @@ AG := $(or \
2025

2126
# Build configuration:
2227
BUILD_DIR := build
23-
LOCKFILE_SOURCE := conanfile.py
24-
BUILD_LOCKFILE := ${BUILD_DIR}/conan.lock
25-
LOCKFILE_OPTION := --lockfile="${CLOE_ROOT}/${BUILD_LOCKFILE}"
2628
INSTALL_DIR := /usr/local
29+
DEPLOY_DIR := deploy
2730
CONAN_OPTIONS :=
2831

32+
# Lockfile for cloe-deployment:
33+
DEPLOY_LOCKFILE_SOURCE := tests/conanfile_deployment.py
34+
DEPLOY_BUILD_LOCKFILE := ${DEPLOY_DIR}/conan.lock
35+
DEPLOY_LOCKFILE_OPTION := --lockfile="${CLOE_ROOT}/${DEPLOY_BUILD_LOCKFILE}"
36+
2937
.DEFAULT_GOAL := help
3038
.PHONY: help
3139
.SILENT: help
3240
help::
3341
$(call print_help_usage)
3442
echo
43+
$(call print_help_section, "Default target")
44+
$(call print_help_target, help, "show this help on available targets")
45+
echo
3546

3647
# Setup targets ---------------------------------------------------------------
3748
include Makefile.setup
3849

50+
${DEPLOY_BUILD_LOCKFILE}:
51+
mkdir -p "${DEPLOY_DIR}"
52+
conan lock create --lockfile-out "${DEPLOY_BUILD_LOCKFILE}" --build -- "${DEPLOY_LOCKFILE_SOURCE}"
53+
54+
.PHONY: lockfile
55+
lockfile: ${DEPLOY_BUILD_LOCKFILE}
56+
3957
# Workspace targets -----------------------------------------------------------
4058
help::
4159
$(call print_help_section, "Available workspace targets")
42-
$(call print_help_target, status, "show status of each of the Conan packages")
43-
$(call print_help_target, smoketest-deps, "build system test pre-requisites")
44-
$(call print_help_target, smoketest, "run system tests")
45-
$(call print_help_target, docs, "generate documentation")
46-
$(call print_help_target, deploy, "deploy Cloe to INSTALL_DIR [=${INSTALL_DIR}]")
47-
$(call print_help_target, deploy-cli, "install ${_yel}cloe-launch${_rst} with ${_dim}${PIPX}${_rst}")
48-
$(call print_help_target, export-cli, "export ${_yel}cloe-launch-profile${_rst} Conan recipe")
60+
$(call print_help_target, docs, "generate Doxygen and Sphinx documentation")
4961
echo
5062

51-
${BUILD_LOCKFILE}:
52-
${MAKE} -f Makefile.package SOURCE_CONANFILE=/dev/null LOCKFILE_SOURCE=${LOCKFILE_SOURCE} ${BUILD_LOCKFILE}
53-
54-
.PHONY: lockfile
55-
lockfile: ${BUILD_LOCKFILE}
63+
.PHONY: docs
64+
docs:
65+
$(call print_header, "Generating Doxygen documentation...")
66+
${MAKE} -C docs doxygen
67+
$(call print_header, "Generating Sphinx documentation...")
68+
${MAKE} -C docs html
5669

57-
.PHONY: status
58-
status: ${BUILD_LOCKFILE}
59-
@for pkg in ${ALL_PKGS}; do \
60-
[ -d $${pkg} ] || continue; \
61-
${MAKE} LOCKFILE_SOURCE="" LOCKFILE_OPTION=${LOCKFILE_OPTION} -C $${pkg} status || true; \
62-
done
70+
help::
71+
$(call print_help_target, export-cli, "export ${_yel}cloe-launch-profile${_rst} Conan recipe")
72+
$(call print_help_target, deploy-cli, "install ${_yel}cloe-launch${_rst} with ${_dim}${PIPX}${_rst}")
73+
echo
6374

64-
.PHONY: deploy
65-
deploy:
66-
$(call print_header, "Deploying binaries to ${INSTALL_DIR}...")
67-
conan install ${CONAN_OPTIONS} --install-folder ${BUILD_DIR}/deploy -g deploy .
68-
mkdir -p ${INSTALL_DIR}
69-
cp -r ${BUILD_DIR}/deploy/cloe-*/* ${INSTALL_DIR}/
75+
.PHONY: export-cli
76+
export-cli:
77+
${MAKE} -C cli export
7078

7179
.PHONY: deploy-cli
7280
deploy-cli:
7381
$(call print_header, "Deploying cloe-launch binary with pip...")
7482
${MAKE} -C cli install
7583

76-
.PHONY: export-cli
77-
export-cli:
78-
${MAKE} -C cli export
84+
help::
85+
$(call print_help_target, lockfile, "create a lockfile for cloe deployment packages")
86+
$(call print_help_target, package-all, "package all cloe deployment packages")
87+
$(call print_help_target, status-all, "show status of each of the Conan packages")
88+
$(call print_help_target, export-all, "export all package sources to Conan cache")
89+
$(call print_help_target, build-all, "build individual packages locally in-source")
90+
$(call print_help_target, deploy-all, "deploy Cloe to INSTALL_DIR [=${INSTALL_DIR}]")
91+
$(call print_help_target, clean-all, "clean entire repository of temporary files")
92+
$(call print_help_target, purge-all, "remove all cloe packages (in any version) from Conan cache")
93+
echo
7994

80-
export: export-cli
81-
package: export-cli
95+
.PHONY: build-all
96+
build-all: lockfile
97+
${MAKE} all-select CONAN_OPTIONS="${CONAN_OPTIONS} ${DEPLOY_LOCKFILE_OPTION}"
8298

83-
.PHONY: docs
84-
docs:
85-
$(call print_header, "Generating Doxygen documentation...")
86-
${MAKE} -C docs doxygen
87-
$(call print_header, "Generating Sphinx documentation...")
88-
${MAKE} -C docs html
99+
.PHONY: status-all
100+
status-all: ${DEPLOY_BUILD_LOCKFILE}
101+
@for pkg in ${ALL_PKGS}; do \
102+
${MAKE} LOCKFILE_SOURCE="" LOCKFILE_OPTION=${DEPLOY_LOCKFILE_OPTION} -C $${pkg} status || true; \
103+
done
89104

90-
.PHONY: smoketest-deps
91-
smoketest-deps: export-cli smoketest-deps-select
105+
.PHONY: export-all
106+
export-all:
107+
$(call print_header, "Exporting all cloe Conan packages...")
108+
${MAKE} export-select export-cli export
109+
110+
.PHONY: deploy-all
111+
deploy-all:
112+
$(call print_header, "Deploying binaries to ${INSTALL_DIR}...")
113+
conan install ${CONAN_OPTIONS} --install-folder ${DEPLOY_DIR} -g deploy .
114+
mkdir -p ${INSTALL_DIR}
115+
cp -r ${DEPLOY_DIR}/cloe-*/* ${INSTALL_DIR}/
92116

93-
.PHONY: smoketest
94-
smoketest: smoketest-select
117+
.PHONY: clean-all
118+
clean-all:
119+
${MAKE} clean clean-select
95120

96121
.PHONY: purge-all
97122
purge-all:
@@ -100,6 +125,10 @@ purge-all:
100125
conan remove -f 'cloe'
101126
conan remove -f 'fable'
102127

128+
.PHONY: package-all
129+
package-all:
130+
conan install ${CONAN_OPTIONS} --install-folder ${DEPLOY_DIR} --build=missing --build=outdated ${DEPLOY_LOCKFILE_SOURCE}
131+
103132
# Development targets ---------------------------------------------------------
104133
help::
105134
$(call print_help_section, "Available development targets")
@@ -122,10 +151,15 @@ todos:
122151
${AG} FIXME
123152
${AG} XXX
124153

154+
# Hidden development targets --------------------------------------------------
155+
125156
.PHONY: grep-uuids
126157
grep-uuids:
127158
${AG} "\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b"
128159

160+
grep-conan-requires:
161+
@rg -t py '^.*requires\(f?["](.+/[0-9]+\.[^)]+)["].*\).*$$' -r '$$1' -I --no-heading --no-line-number | sort | uniq
162+
129163
.PHONY: find-missing-eol
130164
find-missing-eol:
131165
find . -type f -size +0 -exec gawk 'ENDFILE{if ($0 == "") print FILENAME}' {} \;
@@ -134,5 +168,12 @@ find-missing-eol:
134168
sanitize-files:
135169
git grep --cached -Ilz '' | while IFS= read -rd '' f; do tail -c1 < "$$f" | read -r _ || echo >> "$$f"; done
136170

137-
# Build targets ---------------------------------------------------------------
171+
# Micro-packages build targets ------------------------------------------------
138172
include Makefile.all
173+
174+
# Mono-package build targets --------------------------------------------------
175+
DISABLE_HELP_PREAMBLE := true
176+
help::
177+
@printf "Available $(_yel)cloe$(_rst) package targets:\n"
178+
179+
include Makefile.package

Makefile.all

+30-41
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,25 @@ SHELL := /bin/bash
3535
GNUMAKEFLAGS := --no-print-directory
3636
SUBMAKEFLAGS :=
3737

38-
META_PKG := cloe
39-
PLUGIN_PKGS := $(wildcard plugins/*)
40-
ALL_PKGS := fable runtime models oak osi engine ${PLUGIN_PKGS} ${META_PKG}
38+
PLUGIN_PKGS := \
39+
plugins/basic \
40+
plugins/clothoid_fit \
41+
plugins/esmini \
42+
plugins/frustum_culling \
43+
plugins/gndtruth_extractor \
44+
plugins/minimator \
45+
plugins/mocks \
46+
plugins/noisy_sensor \
47+
plugins/speedometer \
48+
plugins/virtue
49+
ALL_PKGS := \
50+
fable \
51+
runtime \
52+
models \
53+
osi \
54+
oak \
55+
engine \
56+
${PLUGIN_PKGS}
4157
WITHOUT_PKGS :=
4258
UNSELECT_PKGS := ${WITHOUT_PKGS}
4359
WITH_PKGS :=
@@ -59,11 +75,11 @@ SELECT_VENDOR := $(call uniq, $(filter-out ${UNSELECT_VENDOR}, ${ALL_VENDOR}) ${
5975
fable:
6076
runtime: fable
6177
models: runtime
78+
osi: runtime models
6279
oak: runtime
6380
engine: models oak
64-
osi: runtime models vendor/open-simulation-interface
6581
${PLUGIN_PKGS}: runtime models
66-
plugins/esmini: vendor/open-simulation-interface vendor/esmini
82+
plugins/esmini: osi
6783

6884
vendor/esmini: vendor/open-simulation-interface
6985
vendor/esmini-data:
@@ -112,18 +128,9 @@ ${1}-each: ${4}
112128
endef
113129

114130
REGEX_TARGET := 's/(-vendor|-select)?-each//'
115-
$(filter-out ${META_PKG}, ${ALL_PKGS} ${ALL_VENDOR}):
131+
${ALL_PKGS} ${ALL_VENDOR}:
116132
${MAKE} -C $@ $(shell echo ${MAKECMDGOALS} | sed -re ${REGEX_TARGET})
117133

118-
# Re-define ${META_PKG} target to use Makefile.package, and only run for targets
119-
# where it makes sense, since "${META_PKG}" is a Conan meta-package.
120-
${META_PKG}:
121-
for case in export package package-outdated list purge clean smoketest smoketest-deps; do \
122-
if [ "$$(echo '${MAKECMDGOALS}' | sed -re ${REGEX_TARGET})" == "$${case}" ]; then \
123-
${MAKE} -f Makefile.package CONAN_OPTIONS="${CONAN_OPTIONS}" $${case} || exit 1; \
124-
fi \
125-
done
126-
127134
# Usage: $(call make_vendor_target, TARGET-NAME, HELP-DESCRIPTION, HELP-CATEGORY)
128135
define make_vendor_target
129136
$(eval $(call _make_target_rules,${1},${2},${3},${SELECT_VENDOR}))
@@ -145,19 +152,16 @@ endef
145152
.PHONY: help
146153
.SILENT: help
147154
help::
148-
$(call print_help_section, "Available build targets")
155+
$(call print_help_section, "Available multi-package targets")
149156

157+
ifneq "${ALL_VENDOR}" ""
158+
help::
150159
$(call make_vendor_target, export-vendor, "export all vendor packages", "[conan-cache]")
151160
$(call make_vendor_target, package-vendor, "create all vendor packages", "[conan-cache]")
152161
$(call make_vendor_target, download-vendor, "download or build vendor packages", "[conan-cache]")
153-
154162
help::
155163
echo
156-
157-
$(call make_every_target, export, "export all package recipes", "[conan-cache]")
158-
help::
159-
$(call print_help_target, package, "create ${META_PKG} package and plugins", "[conan-cache]")
160-
echo
164+
endif
161165

162166
$(call make_select_target, export-select, "export selected packages", "[conan-cache]")
163167
$(call make_select_target, package-select, "create selected packages with policy", "[conan-cache]")
@@ -185,34 +189,19 @@ $(call make_select_target, clean-select, "remove build artifacts", "[in-source]"
185189
help::
186190
echo
187191
$(call print_help_subsection, "Options")
192+
ifneq "${ALL_VENDOR}" ""
188193
$(call print_help_option, WITH_VENDOR, "", "include optional vendor packages from ${_grn}UNSELECT_VENDOR${_rst}")
194+
endif
189195
$(call print_help_option, WITH_PKGS, "", "include optional packages from ${_grn}UNSELECT_PKGS${_rst}")
190196
$(call print_help_option, LOCKFILE_SOURCE, "", "use specified conanfile as lockfile source for build")
191197
echo
192198
$(call print_help_subsection, "Defines")
193199
$(call print_help_option, BUILD_POLICY, ${BUILD_POLICY})
194200
$(call print_help_define, CONAN_OPTIONS, ${CONAN_OPTIONS})
201+
ifneq "${ALL_VENDOR}" ""
195202
$(call print_help_define_lines, UNSELECT_VENDOR, ${UNSELECT_VENDOR})
196203
$(call print_help_define_lines, SELECT_VENDOR, ${SELECT_VENDOR})
204+
endif
197205
$(call print_help_define_lines, UNSELECT_PKGS, ${UNSELECT_PKGS})
198206
$(call print_help_define_lines, SELECT_PKGS, ${SELECT_PKGS})
199207
echo
200-
201-
.PHONY: package
202-
package: export-select
203-
# Build cloe with all targets and options together.
204-
#
205-
# This is different from the package target in that it always builds the
206-
# packages from this workspace, the ones in SELECT_PKGS.
207-
# This is different from the package-select target in that it builds them
208-
# all together and thereby uses the correct dependency resolution with
209-
# overrides and options.
210-
TARGETS=$$( \
211-
for pkg in ${SELECT_PKGS}; do \
212-
if [ ! -d $${pkg} ]; then \
213-
continue; \
214-
fi; \
215-
echo -n "--build=$$(make --no-print-directory -C $${pkg} info-name) "; \
216-
done; \
217-
) && \
218-
${MAKE} -f Makefile.package CONAN_OPTIONS="${CONAN_OPTIONS} $$TARGETS" package

0 commit comments

Comments
 (0)