diff --git a/.github/workflows/build-cloe.yaml b/.github/workflows/build-cloe.yaml index 43eb30249..e0a3f27b8 100644 --- a/.github/workflows/build-cloe.yaml +++ b/.github/workflows/build-cloe.yaml @@ -1,6 +1,19 @@ +--- name: Build Cloe on: + push: + branches: + - master + - develop + - "release/**" + paths-ignore: + - "*.md" + - ".gitignore" + - "LICENSE" + - "dist/**" + - "docs/**" + - "ui/**" pull_request: paths-ignore: - "*.md" @@ -22,7 +35,16 @@ jobs: - "cloe-normal" package_target: # 1. Build each test configuration in Conan cache and run all tests - - "export export-vendor smoketest-deps smoketest" + - "export-vendor export-all smoketest-deps smoketest" + + # 2. Build cloe super-package in editable mode and run tests + - "export-vendor editable all smoketest TEST_CONANFILES=tests/conanfile_superbuild.py" + + # 3. TODO: Build individual packages in editable mode and run tests + # This cannot be currently enabled because of a Conan deficiency in v1. + # Once all build tooling is based on Conan v2, we can re-enable this use-case. + # Until then, use the previous target for this use-case. + # - "export-vendor editable-select build-all smoketest TEST_CONANFILES=tests/conanfile_deployment.py" env: CONAN_NON_INTERACTIVE: "yes" DEBIAN_FRONTEND: noninteractive diff --git a/.github/workflows/build-docs.yaml b/.github/workflows/build-docs.yaml index 61f9b4113..75b5cbea6 100644 --- a/.github/workflows/build-docs.yaml +++ b/.github/workflows/build-docs.yaml @@ -1,6 +1,15 @@ +--- name: Build Documentation on: + push: + branches: + - master + - develop + - "release/**" + paths: + - "docs/**" + - "*.hpp" pull_request: paths: - "docs/**" diff --git a/.github/workflows/build-ui.yaml b/.github/workflows/build-ui.yaml index edb828ac3..8f64e1d53 100644 --- a/.github/workflows/build-ui.yaml +++ b/.github/workflows/build-ui.yaml @@ -1,6 +1,14 @@ +--- name: Build UI on: + push: + branches: + - master + - develop + - "release/**" + paths: + - "ui/**" pull_request: paths: - "ui/**" @@ -29,8 +37,7 @@ jobs: echo $version if [[ $version == "v18"* ]]; then npm run build_v18 - else + else npm run build fi shell: bash - diff --git a/.gitignore b/.gitignore index be2327278..6cd13c76c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ CMakeFiles/ compile_commands.json # Files generated by Clang: +.cache/ .clangd/ .cache/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..d50488e7d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +# This CMakeLists.txt configures a super-build containing everything +# from this repo. +# +# It is currently experimental. +# + +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) + +project(cloe LANGUAGES CXX) + +option(CLOE_WITH_ESMINI "Build simulator_esmini plugin?" ON) +option(CLOE_WITH_VTD "Build simulator_vtd plugin?" OFF) + +set(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/runtime/cmake") + +# Since a super-build does not export packages individually via Conan, +# we cannot depend on Conan-generated CMake config files, instead we +# use the CMake targets directly as if they were already found. +set(CLOE_FIND_PACKAGES OFF CACHE BOOL "Call find_package() for cloe packages" FORCE) + +# Ensure output goes to one place so cloe-launch can find the plugins +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) + +# Ensure we can test from this level. +set(CMAKE_CTEST_ARGUMENTS "--output-on-failure") +include(CTest) + +# Order matters: +add_subdirectory(fable) +add_subdirectory(runtime) +add_subdirectory(models) +add_subdirectory(osi) +add_subdirectory(oak) +add_subdirectory(engine) +add_subdirectory(plugins) + +if(CLOE_WITH_VTD) + add_subdirectory(optional/vtd) +endif() diff --git a/Makefile b/Makefile index ee93372a1..0677e2086 100644 --- a/Makefile +++ b/Makefile @@ -3,10 +3,15 @@ # This file contains Makefile targets for the cloe project. # +# Make configuration: +SHELL := /bin/bash +GNUMAKEFLAGS := --no-print-directory +SUBMAKEFLAGS := + CLOE_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) -CLOE_LAUNCH := PYTHONPATH="${CLOE_ROOT}/cli" python3 -m cloe_launch +CLOE_LAUNCH := PYTHONPATH="$(CLOE_ROOT)/cli" python3 -m cloe_launch -include ${CLOE_ROOT}/Makefile.help +include $(CLOE_ROOT)/Makefile.help # Set the clang-format command line to use: CLANG_FORMAT := $(shell command -v clang-format 2>/dev/null) @@ -20,78 +25,96 @@ AG := $(or \ # Build configuration: BUILD_DIR := build -LOCKFILE_SOURCE := conanfile.py -BUILD_LOCKFILE := ${BUILD_DIR}/conan.lock -LOCKFILE_OPTION := --lockfile="${CLOE_ROOT}/${BUILD_LOCKFILE}" INSTALL_DIR := /usr/local +DEPLOY_DIR := deploy CONAN_OPTIONS := +# Lockfile for cloe-deployment: +DEPLOY_LOCKFILE_SOURCE := tests/conanfile_deployment.py +DEPLOY_BUILD_LOCKFILE := $(DEPLOY_DIR)/conan.lock +DEPLOY_LOCKFILE_OPTION := --lockfile="$(CLOE_ROOT)/$(DEPLOY_BUILD_LOCKFILE)" + .DEFAULT_GOAL := help .PHONY: help .SILENT: help help:: $(call print_help_usage) echo + $(call print_help_section, "Default target") + $(call print_help_target, help, "show this help on available targets") + echo # Setup targets --------------------------------------------------------------- include Makefile.setup +$(DEPLOY_BUILD_LOCKFILE): + mkdir -p "$(DEPLOY_DIR)" + conan lock create --lockfile-out "$(DEPLOY_BUILD_LOCKFILE)" --build -- "$(DEPLOY_LOCKFILE_SOURCE)" + +.PHONY: lockfile +lockfile: $(DEPLOY_BUILD_LOCKFILE) + # Workspace targets ----------------------------------------------------------- help:: $(call print_help_section, "Available workspace targets") - $(call print_help_target, status, "show status of each of the Conan packages") - $(call print_help_target, smoketest-deps, "build system test pre-requisites") - $(call print_help_target, smoketest, "run system tests") - $(call print_help_target, docs, "generate documentation") - $(call print_help_target, deploy, "deploy Cloe to INSTALL_DIR [=${INSTALL_DIR}]") - $(call print_help_target, deploy-cli, "install ${_yel}cloe-launch${_rst} with ${_dim}${PIPX}${_rst}") - $(call print_help_target, export-cli, "export ${_yel}cloe-launch-profile${_rst} Conan recipe") + $(call print_help_target, docs, "generate Doxygen and Sphinx documentation") echo -${BUILD_LOCKFILE}: - ${MAKE} -f Makefile.package SOURCE_CONANFILE=/dev/null LOCKFILE_SOURCE=${LOCKFILE_SOURCE} ${BUILD_LOCKFILE} - -.PHONY: lockfile -lockfile: ${BUILD_LOCKFILE} +.PHONY: docs +docs: + $(call print_header, "Generating Doxygen documentation...") + $(MAKE) -C docs doxygen + $(call print_header, "Generating Sphinx documentation...") + $(MAKE) -C docs html -.PHONY: status -status: ${BUILD_LOCKFILE} - @for pkg in ${ALL_PKGS}; do \ - [ -d $${pkg} ] || continue; \ - ${MAKE} LOCKFILE_SOURCE="" LOCKFILE_OPTION=${LOCKFILE_OPTION} -C $${pkg} status || true; \ - done +help:: + $(call print_help_target, export-cli, "export $(_yel)cloe-launch-profile$(_rst) Conan recipe") + $(call print_help_target, deploy-cli, "install $(_yel)cloe-launch$(_rst) with $(_dim)$(PIPX)$(_rst)") + echo -.PHONY: deploy -deploy: - $(call print_header, "Deploying binaries to ${INSTALL_DIR}...") - conan install ${CONAN_OPTIONS} --install-folder ${BUILD_DIR}/deploy -g deploy . - mkdir -p ${INSTALL_DIR} - cp -r ${BUILD_DIR}/deploy/cloe-*/* ${INSTALL_DIR}/ +.PHONY: export-cli +export-cli: + $(MAKE) -C cli export .PHONY: deploy-cli deploy-cli: $(call print_header, "Deploying cloe-launch binary with pip...") - ${MAKE} -C cli install + $(MAKE) -C cli install -.PHONY: export-cli -export-cli: - ${MAKE} -C cli export +help:: + $(call print_help_target, lockfile, "create a lockfile for cloe deployment packages") + $(call print_help_target, package-all, "package all cloe deployment packages") + $(call print_help_target, status-all, "show status of each of the Conan packages") + $(call print_help_target, export-all, "export all package sources to Conan cache") + $(call print_help_target, build-all, "build individual packages locally in-source") + $(call print_help_target, deploy-all, "deploy $(_yel)cloe$(_rst) to $(_grn)INSTALL_DIR$(_rst)=$(_dim)$(INSTALL_DIR)$(_rst)") + $(call print_help_target, clean-all, "clean entire repository of temporary files") + $(call print_help_target, purge-all, "remove all cloe packages (in any version) from Conan cache") + echo -export: export-cli -package: export-cli +.PHONY: build-all +build-all: lockfile + $(MAKE) all-select CONAN_OPTIONS="$(CONAN_OPTIONS) $(DEPLOY_LOCKFILE_OPTION)" -.PHONY: docs -docs: - $(call print_header, "Generating Doxygen documentation...") - ${MAKE} -C docs doxygen - $(call print_header, "Generating Sphinx documentation...") - ${MAKE} -C docs html +.PHONY: status-all +status-all: $(DEPLOY_BUILD_LOCKFILE) + @for pkg in $(ALL_PKGS); do \ + $(MAKE) LOCKFILE_SOURCE="" LOCKFILE_OPTION=$(DEPLOY_LOCKFILE_OPTION) -C $${pkg} status || true; \ + done + +.PHONY: export-all +export-all: + $(call print_header, "Exporting all cloe Conan packages...") + $(MAKE) export-select export-cli export -.PHONY: smoketest-deps -smoketest-deps: export-cli smoketest-deps-select +.PHONY: deploy-all +deploy-all: + $(call print_header, "Deploying binaries to $(INSTALL_DIR)...") + $(CLOE_LAUNCH) deploy -D $(DEPLOY_DIR) $(DEPLOY_LOCKFILE_SOURCE) $(CONAN_OPTIONS) -.PHONY: smoketest -smoketest: smoketest-select +.PHONY: clean-all +clean-all: + $(MAKE) clean clean-select .PHONY: purge-all purge-all: @@ -100,6 +123,10 @@ purge-all: conan remove -f 'cloe' conan remove -f 'fable' +.PHONY: package-all +package-all: + conan install $(CONAN_OPTIONS) --install-folder $(DEPLOY_DIR) --build=missing --build=outdated $(DEPLOY_LOCKFILE_SOURCE) + # Development targets --------------------------------------------------------- help:: $(call print_help_section, "Available development targets") @@ -114,17 +141,22 @@ format: # continues to work as expected. # # See: https://www.moxio.com/blog/43/ignoring-bulk-change-commits-with-git-blame - find . -type f -not -path '*/\.git/*' -and \( -name '*.cpp' -o -name '*.hpp' \) -exec ${CLANG_FORMAT} ${CLANG_FORMAT_ARGS} -i {} \; + find . -type f -not -path '*/\.git/*' -and \( -name '*.cpp' -o -name '*.hpp' \) -exec $(CLANG_FORMAT) $(CLANG_FORMAT_ARGS) -i {} \; .PHONY: todos todos: - ${AG} TODO - ${AG} FIXME - ${AG} XXX + $(AG) TODO + $(AG) FIXME + $(AG) XXX + +# Hidden development targets -------------------------------------------------- .PHONY: grep-uuids grep-uuids: - ${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" + $(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" + +grep-conan-requires: + @rg -t py '^.*requires\(f?["](.+/[0-9]+\.[^)]+)["].*\).*$$' -r '$$1' -I --no-heading --no-line-number | sort | uniq .PHONY: find-missing-eol find-missing-eol: @@ -134,5 +166,12 @@ find-missing-eol: sanitize-files: git grep --cached -Ilz '' | while IFS= read -rd '' f; do tail -c1 < "$$f" | read -r _ || echo >> "$$f"; done -# Build targets --------------------------------------------------------------- +# Micro-packages build targets ------------------------------------------------ include Makefile.all + +# Mono-package build targets -------------------------------------------------- +DISABLE_HELP_PREAMBLE := true +help:: + @printf "Available $(_yel)cloe$(_rst) package targets:\n" + +include Makefile.package diff --git a/Makefile.all b/Makefile.all index fbf633780..c6756f0e1 100644 --- a/Makefile.all +++ b/Makefile.all @@ -35,14 +35,30 @@ SHELL := /bin/bash GNUMAKEFLAGS := --no-print-directory SUBMAKEFLAGS := -META_PKG := cloe -PLUGIN_PKGS := $(wildcard plugins/*) -ALL_PKGS := fable runtime models oak osi engine ${PLUGIN_PKGS} ${META_PKG} +PLUGIN_PKGS := \ + plugins/basic \ + plugins/clothoid_fit \ + plugins/esmini \ + plugins/frustum_culling \ + plugins/gndtruth_extractor \ + plugins/minimator \ + plugins/mocks \ + plugins/noisy_sensor \ + plugins/speedometer \ + plugins/virtue +ALL_PKGS := \ + fable \ + runtime \ + models \ + osi \ + oak \ + engine \ + $(PLUGIN_PKGS) WITHOUT_PKGS := -UNSELECT_PKGS := ${WITHOUT_PKGS} +UNSELECT_PKGS := $(WITHOUT_PKGS) WITH_PKGS := -SELECT_PKGS := $(call uniq, $(filter-out ${UNSELECT_PKGS}, ${ALL_PKGS}) ${WITH_PKGS}) -.PHONY: ${ALL_PKGS} +SELECT_PKGS := $(call uniq, $(filter-out $(UNSELECT_PKGS), $(ALL_PKGS)) $(WITH_PKGS)) +.PHONY: $(ALL_PKGS) ## VENDOR PACKAGE SELECTION ## @@ -50,20 +66,20 @@ SELECT_PKGS := $(call uniq, $(filter-out ${UNSELECT_PKGS}, ${ALL_PKGS}) ${WITH_P ## ALL_VENDOR := $(wildcard vendor/*) WITHOUT_VENDOR := -UNSELECT_VENDOR := ${WITHOUT_VENDOR} +UNSELECT_VENDOR := $(WITHOUT_VENDOR) WITH_VENDOR := -SELECT_VENDOR := $(call uniq, $(filter-out ${UNSELECT_VENDOR}, ${ALL_VENDOR}) ${WITH_VENDOR}) -.PHONY: ${ALL_VENDOR} +SELECT_VENDOR := $(call uniq, $(filter-out $(UNSELECT_VENDOR), $(ALL_VENDOR)) $(WITH_VENDOR)) +.PHONY: $(ALL_VENDOR) # Specify dependencies: fable: runtime: fable models: runtime +osi: runtime models oak: runtime engine: models oak -osi: runtime models vendor/open-simulation-interface -${PLUGIN_PKGS}: runtime models -plugins/esmini: vendor/open-simulation-interface vendor/esmini +$(PLUGIN_PKGS): runtime models +plugins/esmini: osi vendor/esmini: vendor/open-simulation-interface vendor/esmini-data: @@ -98,45 +114,36 @@ CONAN_OPTIONS := # Usage: $(call _make_target_rule, TARGET-NAME, MAKE-TARGET, HELP-DESCRIPTION, MAKE-ARGUMENTS) define _make_target_rule -${1}: - $(call print_header, "Proceeding to $(call unquote, ${3})") - ${MAKE} ${SUBMAKEFLAGS} ${4} ${2} +$(1): + $(call print_header, "Proceeding to $(call unquote, $(3))") + $(MAKE) $(SUBMAKEFLAGS) $(4) $(2) endef # Usage: $(call _make_target_rules, TARGET-NAME, HELP-DESCRIPTION, HELP-CATEGORY, PACKAGE-DIRS) define _make_target_rules help:: - $(call print_help_target, ${1}, ${2}, ${3}) -$(call _make_target_rule,${1},${1}-each,${2},-f Makefile.all) -${1}-each: ${4} + $(call print_help_target, $(1), $(2), $(3)) +$(call _make_target_rule,$(1),$(1)-each,$(2),-f Makefile.all) +$(1)-each: $(4) endef REGEX_TARGET := 's/(-vendor|-select)?-each//' -$(filter-out ${META_PKG}, ${ALL_PKGS} ${ALL_VENDOR}): - ${MAKE} -C $@ $(shell echo ${MAKECMDGOALS} | sed -re ${REGEX_TARGET}) - -# Re-define ${META_PKG} target to use Makefile.package, and only run for targets -# where it makes sense, since "${META_PKG}" is a Conan meta-package. -${META_PKG}: - for case in export package package-outdated list purge clean smoketest smoketest-deps; do \ - if [ "$$(echo '${MAKECMDGOALS}' | sed -re ${REGEX_TARGET})" == "$${case}" ]; then \ - ${MAKE} -f Makefile.package CONAN_OPTIONS="${CONAN_OPTIONS}" $${case} || exit 1; \ - fi \ - done +$(ALL_PKGS) $(ALL_VENDOR): + $(MAKE) -C $@ $(shell echo $(MAKECMDGOALS) | sed -re $(REGEX_TARGET)) # Usage: $(call make_vendor_target, TARGET-NAME, HELP-DESCRIPTION, HELP-CATEGORY) define make_vendor_target -$(eval $(call _make_target_rules,${1},${2},${3},${SELECT_VENDOR})) +$(eval $(call _make_target_rules,$(1),$(2),$(3),$(SELECT_VENDOR))) endef # Usage: $(call make_every_target, TARGET-NAME, HELP-DESCRIPTION, HELP-CATEGORY) define make_every_target -$(eval $(call _make_target_rules,${1},${2},${3},${ALL_PKGS})) +$(eval $(call _make_target_rules,$(1),$(2),$(3),$(ALL_PKGS))) endef # Usage: $(call make_select_target, TARGET-NAME, HELP-DESCRIPTION, HELP-CATEGORY) define make_select_target -$(eval $(call _make_target_rules,${1},${2},${3},${SELECT_PKGS})) +$(eval $(call _make_target_rules,$(1),$(2),$(3),$(SELECT_PKGS))) endef # --------------------------------------------------------------------------- # @@ -145,19 +152,16 @@ endef .PHONY: help .SILENT: help help:: - $(call print_help_section, "Available build targets") + $(call print_help_section, "Available multi-package targets") +ifneq "$(ALL_VENDOR)" "" +help:: $(call make_vendor_target, export-vendor, "export all vendor packages", "[conan-cache]") $(call make_vendor_target, package-vendor, "create all vendor packages", "[conan-cache]") $(call make_vendor_target, download-vendor, "download or build vendor packages", "[conan-cache]") - -help:: - echo - -$(call make_every_target, export, "export all package recipes", "[conan-cache]") help:: - $(call print_help_target, package, "create ${META_PKG} package and plugins", "[conan-cache]") echo +endif $(call make_select_target, export-select, "export selected packages", "[conan-cache]") $(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]" help:: echo $(call print_help_subsection, "Options") - $(call print_help_option, WITH_VENDOR, "", "include optional vendor packages from ${_grn}UNSELECT_VENDOR${_rst}") - $(call print_help_option, WITH_PKGS, "", "include optional packages from ${_grn}UNSELECT_PKGS${_rst}") +ifneq "$(ALL_VENDOR)" "" + $(call print_help_option, WITH_VENDOR, "", "include optional vendor packages from $(_grn)UNSELECT_VENDOR$(_rst)") +endif + $(call print_help_option, WITH_PKGS, "", "include optional packages from $(_grn)UNSELECT_PKGS$(_rst)") $(call print_help_option, LOCKFILE_SOURCE, "", "use specified conanfile as lockfile source for build") echo $(call print_help_subsection, "Defines") - $(call print_help_option, BUILD_POLICY, ${BUILD_POLICY}) - $(call print_help_define, CONAN_OPTIONS, ${CONAN_OPTIONS}) - $(call print_help_define_lines, UNSELECT_VENDOR, ${UNSELECT_VENDOR}) - $(call print_help_define_lines, SELECT_VENDOR, ${SELECT_VENDOR}) - $(call print_help_define_lines, UNSELECT_PKGS, ${UNSELECT_PKGS}) - $(call print_help_define_lines, SELECT_PKGS, ${SELECT_PKGS}) + $(call print_help_option, BUILD_POLICY, $(BUILD_POLICY)) + $(call print_help_define, CONAN_OPTIONS, $(CONAN_OPTIONS)) +ifneq "$(ALL_VENDOR)" "" + $(call print_help_define_lines, UNSELECT_VENDOR, $(UNSELECT_VENDOR)) + $(call print_help_define_lines, SELECT_VENDOR, $(SELECT_VENDOR)) +endif + $(call print_help_define_lines, UNSELECT_PKGS, $(UNSELECT_PKGS)) + $(call print_help_define_lines, SELECT_PKGS, $(SELECT_PKGS)) echo - -.PHONY: package -package: export-select - # Build cloe with all targets and options together. - # - # This is different from the package target in that it always builds the - # packages from this workspace, the ones in SELECT_PKGS. - # This is different from the package-select target in that it builds them - # all together and thereby uses the correct dependency resolution with - # overrides and options. - TARGETS=$$( \ - for pkg in ${SELECT_PKGS}; do \ - if [ ! -d $${pkg} ]; then \ - continue; \ - fi; \ - echo -n "--build=$$(make --no-print-directory -C $${pkg} info-name) "; \ - done; \ - ) && \ - ${MAKE} -f Makefile.package CONAN_OPTIONS="${CONAN_OPTIONS} $$TARGETS" package diff --git a/Makefile.docker b/Makefile.docker index 298004c71..5a1b31438 100644 --- a/Makefile.docker +++ b/Makefile.docker @@ -2,61 +2,61 @@ # # This file defines all Docker targets. -PROJECT_ROOT := $(dir $(abspath $(lastword ${MAKEFILE_LIST}))) -PROJECT_VERSION := $(shell make --no-print-directory -C ${PROJECT_ROOT} -f Makefile.package info-version) +PROJECT_ROOT := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +PROJECT_VERSION := $(shell make --no-print-directory -C $(PROJECT_ROOT) -f Makefile.package info-version) UBUNTU_NAME := ubuntu UBUNTU_VERSIONS := 20.04 22.04 DOCKER := DOCKER_BUILDKIT=1 docker DOCKER_IMAGE_NAME := cloe/cloe-engine -DOCKER_IMAGE_VERSION := ${PROJECT_VERSION} -DOCKER_IMAGE := ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION} -DOCKER_DEVIMAGE := ${DOCKER_IMAGE_NAME}-dev:${DOCKER_IMAGE_VERSION} -DOCKER_CONTEXT := ${PROJECT_ROOT} +DOCKER_IMAGE_VERSION := $(PROJECT_VERSION) +DOCKER_IMAGE := $(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_VERSION) +DOCKER_DEVIMAGE := $(DOCKER_IMAGE_NAME)-dev:$(DOCKER_IMAGE_VERSION) +DOCKER_CONTEXT := $(PROJECT_ROOT) DOCKER_USER_ARGS += -DOCKER_BUILD_ARGS += --build-arg PROJECT_VERSION=${PROJECT_VERSION} +DOCKER_BUILD_ARGS += --build-arg PROJECT_VERSION=$(PROJECT_VERSION) DOCKER_RUN_ARGS += --rm -ifndef (${https_proxy},) +ifndef ($(https_proxy),) DOCKER_NETWORK := host DOCKER_BUILD_ARGS += --network=host \ - --build-arg https_proxy="${https_proxy}" \ - --build-arg http_proxy="${http_proxy}" \ - --build-arg no_proxy="${no_proxy}" + --build-arg https_proxy="$(https_proxy)" \ + --build-arg http_proxy="$(http_proxy)" \ + --build-arg no_proxy="$(no_proxy)" DOCKER_RUN_ARGS += --network=host \ - --env https_proxy="${https_proxy}" \ - --env http_proxy="${http_proxy}" \ - --env no_proxy="${no_proxy}" + --env https_proxy="$(https_proxy)" \ + --env http_proxy="$(http_proxy)" \ + --env no_proxy="$(no_proxy)" else DOCKER_NETWORK := internal endif -ifeq ($(shell [ -f ${PROJECT_ROOT}/setup.sh ] && echo "true"),true) -DOCKER_BUILD_ARGS += --secret id=setup,src=${PROJECT_ROOT}/setup.sh -DOCKER_RUN_ARGS += -v "${PROJECT_ROOT}/setup.sh:/root/setup.sh" +ifeq ($(shell [ -f $(PROJECT_ROOT)/setup.sh ] && echo "true"),true) +DOCKER_BUILD_ARGS += --secret id=setup,src=$(PROJECT_ROOT)/setup.sh +DOCKER_RUN_ARGS += -v "$(PROJECT_ROOT)/setup.sh:/root/setup.sh" endif -ifneq (${CONAN_PROFILE},) -DOCKER_BUILD_ARGS += --build-arg CONAN_PROFILE="${CONAN_PROFILE}" +ifneq ($(CONAN_PROFILE),) +DOCKER_BUILD_ARGS += --build-arg CONAN_PROFILE="$(CONAN_PROFILE)" endif -ifneq (${VENDOR_TARGET},) -DOCKER_BUILD_ARGS += --build-arg VENDOR_TARGET="${VENDOR_TARGET}" +ifneq ($(VENDOR_TARGET),) +DOCKER_BUILD_ARGS += --build-arg VENDOR_TARGET="$(VENDOR_TARGET)" endif -ifneq (${PACKAGE_TARGET},) -DOCKER_BUILD_ARGS += --build-arg PACKAGE_TARGET="${PACKAGE_TARGET}" +ifneq ($(PACKAGE_TARGET),) +DOCKER_BUILD_ARGS += --build-arg PACKAGE_TARGET="$(PACKAGE_TARGET)" endif -ifeq (${KEEP_SOURCES},1) +ifeq ($(KEEP_SOURCES),1) DOCKER_BUILD_ARGS += --build-arg KEEP_SOURCES=1 endif # ----------------------------------------------------------------------------- -include ${PROJECT_ROOT}/Makefile.help +include $(PROJECT_ROOT)/Makefile.help .PHONY: help .SILENT: help @@ -73,25 +73,25 @@ help:: $(call print_help_target, run-ubuntu-VERSION, "run the Ubuntu VERSION image") $(call print_help_target, release-all, "release all Ubuntu versions") $(call print_help_target, release-ubuntu-VERSION, "release the Ubuntu VERSION image") - $(call print_help_target, remove-current-images, "remove and prune all ${DOCKER_IMAGE} Docker images") - $(call print_help_target, remove-all-images, "remove and prune all ${DOCKER_IMAGE_NAME} Docker images") + $(call print_help_target, remove-current-images, "remove and prune all $(DOCKER_IMAGE) Docker images") + $(call print_help_target, remove-all-images, "remove and prune all $(DOCKER_IMAGE_NAME) Docker images") echo $(call print_help_section, "User configuration") - $(call print_help_define, CONAN_PROFILE, ${CONAN_PROFILE}) - $(call print_help_define, VENDOR_TARGET, ${VENDOR_TARGET}) - $(call print_help_define, PACKAGE_TARGET, ${PACKAGE_TARGET}) - $(call print_help_define, KEEP_SOURCES, ${KEEP_SOURCES}) - $(call print_help_args_lines, DOCKER_USER_ARGS, ${DOCKER_USER_ARGS}) + $(call print_help_define, CONAN_PROFILE, $(CONAN_PROFILE)) + $(call print_help_define, VENDOR_TARGET, $(VENDOR_TARGET)) + $(call print_help_define, PACKAGE_TARGET, $(PACKAGE_TARGET)) + $(call print_help_define, KEEP_SOURCES, $(KEEP_SOURCES)) + $(call print_help_args_lines, DOCKER_USER_ARGS, $(DOCKER_USER_ARGS)) echo $(call print_help_section, "Docker configuration") - $(call print_help_define, UBUNTU_NAME, "${UBUNTU_NAME}") - $(call print_help_define_lines, UBUNTU_VERSIONS, ${UBUNTU_VERSIONS}) - $(call print_help_define, DOCKER, "${DOCKER}") - $(call print_help_define, DOCKER_CONTEXT, "${DOCKER_CONTEXT}") - $(call print_help_define, DOCKER_NETWORK, "${DOCKER_NETWORK}") - $(call print_help_define, DOCKER_IMAGE, "${DOCKER_IMAGE}") - $(call print_help_args_lines, DOCKER_BUILD_ARGS, ${DOCKER_BUILD_ARGS}) - $(call print_help_args_lines, DOCKER_RUN_ARGS, ${DOCKER_RUN_ARGS}) + $(call print_help_define, UBUNTU_NAME, "$(UBUNTU_NAME)") + $(call print_help_define_lines, UBUNTU_VERSIONS, $(UBUNTU_VERSIONS)) + $(call print_help_define, DOCKER, "$(DOCKER)") + $(call print_help_define, DOCKER_CONTEXT, "$(DOCKER_CONTEXT)") + $(call print_help_define, DOCKER_NETWORK, "$(DOCKER_NETWORK)") + $(call print_help_define, DOCKER_IMAGE, "$(DOCKER_IMAGE)") + $(call print_help_args_lines, DOCKER_BUILD_ARGS, $(DOCKER_BUILD_ARGS)) + $(call print_help_args_lines, DOCKER_RUN_ARGS, $(DOCKER_RUN_ARGS)) echo .SILENT: FORCE @@ -101,61 +101,61 @@ FORCE: # prerequisites of every target with patterns. .PHONY: build-all -build-all: $(addprefix build-ubuntu-,${UBUNTU_VERSIONS}) +build-all: $(addprefix build-ubuntu-,$(UBUNTU_VERSIONS)) .PHONY: test-all -test-all: $(addprefix test-ubuntu-,${UBUNTU_VERSIONS}) +test-all: $(addprefix test-ubuntu-,$(UBUNTU_VERSIONS)) .PHONY: release-all -release-all: $(addprefix release-ubuntu-,${UBUNTU_VERSIONS}) +release-all: $(addprefix release-ubuntu-,$(UBUNTU_VERSIONS)) ubuntu-%: FORCE build-ubuntu-% test-ubuntu-% @echo - @echo "Completed building and testing: ${DOCKER_IMAGE}-$@" + @echo "Completed building and testing: $(DOCKER_IMAGE)-$@" .PHONY: all -all: $(addprefix ubuntu-,${UBUNTU_VERSIONS}) +all: $(addprefix ubuntu-,$(UBUNTU_VERSIONS)) build-devc-%: FORCE Dockerfile - ${DOCKER} build -f Dockerfile ${DOCKER_BUILD_ARGS} ${DOCKER_USER_ARGS} \ + $(DOCKER) build -f Dockerfile $(DOCKER_BUILD_ARGS) $(DOCKER_USER_ARGS) \ --build-arg UBUNTU_VERSION=$* \ --target stage-setup-system \ - -t ${DOCKER_DEVIMAGE}-ubuntu-$* \ - ${DOCKER_CONTEXT} + -t $(DOCKER_DEVIMAGE)-ubuntu-$* \ + $(DOCKER_CONTEXT) build-ubuntu-%: FORCE Dockerfile - ${DOCKER} build -f Dockerfile ${DOCKER_BUILD_ARGS} ${DOCKER_USER_ARGS} \ + $(DOCKER) build -f Dockerfile $(DOCKER_BUILD_ARGS) $(DOCKER_USER_ARGS) \ --build-arg UBUNTU_VERSION=$* \ - -t ${DOCKER_IMAGE}-ubuntu-$* \ - ${DOCKER_CONTEXT} + -t $(DOCKER_IMAGE)-ubuntu-$* \ + $(DOCKER_CONTEXT) test-ubuntu-%: FORCE - docker run ${DOCKER_RUN_ARGS} ${DOCKER_USER_ARGS} ${DOCKER_IMAGE}-ubuntu-$* \ + docker run $(DOCKER_RUN_ARGS) $(DOCKER_USER_ARGS) $(DOCKER_IMAGE)-ubuntu-$* \ bash -ec "[ -f /root/setup.sh ] && source /root/setup.sh; make smoketest" run-devc-%: FORCE - docker run -it ${DOCKER_RUN_ARGS} ${DOCKER_USER_ARGS} --mount type=bind,source=$$(pwd),destination=/cloe ${DOCKER_DEVIMAGE}-ubuntu-$* + docker run -it $(DOCKER_RUN_ARGS) $(DOCKER_USER_ARGS) --mount type=bind,source=$$(pwd),destination=/cloe $(DOCKER_DEVIMAGE)-ubuntu-$* run-ubuntu-%: FORCE - docker run -it ${DOCKER_RUN_ARGS} ${DOCKER_USER_ARGS} ${DOCKER_IMAGE}-ubuntu-$* + docker run -it $(DOCKER_RUN_ARGS) $(DOCKER_USER_ARGS) $(DOCKER_IMAGE)-ubuntu-$* release-ubuntu-%: FORCE @test -f setup.sh || echo 'Error: require setup.sh for user authentication' - ${DOCKER} run ${DOCKER_RUN_ARGS} ${DOCKER_USER_ARGS} ${DOCKER_IMAGE}-ubuntu-$* \ + $(DOCKER) run $(DOCKER_RUN_ARGS) $(DOCKER_USER_ARGS) $(DOCKER_IMAGE)-ubuntu-$* \ bash -ec 'source /root/setup.sh && upload_conan_packages' .PHONY: require-setup-sh require-setup-sh: - @if [ ! -f ${PROJECT_ROOT}/setup.sh ]; then \ - echo "ERROR: require ${PROJECT_ROOT}/setup.sh to proceed"; \ + @if [ ! -f $(PROJECT_ROOT)/setup.sh ]; then \ + echo "ERROR: require $(PROJECT_ROOT)/setup.sh to proceed"; \ exit 1; \ fi .PHONY: remove-current-images remove-current-images: - docker rmi $$(docker images --format '{{.Repository}}:{{.Tag}}' | grep '${DOCKER_IMAGE}') + docker rmi $$(docker images --format '{{.Repository}}:{{.Tag}}' | grep '$(DOCKER_IMAGE)') .PHONY: remove-all-images remove-all-images: - docker rmi $$(docker images --format '{{.Repository}}:{{.Tag}}' | grep '${DOCKER_IMAGE_NAME}:') + docker rmi $$(docker images --format '{{.Repository}}:{{.Tag}}' | grep '$(DOCKER_IMAGE_NAME):') diff --git a/Makefile.help b/Makefile.help index 84fdc9b0f..2a0bc50a8 100644 --- a/Makefile.help +++ b/Makefile.help @@ -21,10 +21,10 @@ # Usage: $(call assert_numeric_bool, VARIABLE-NAME) define assert_numeric_bool -$(if $(filter-out 0 1,${$1}), $(error Unexpected value for parameter $1, expect either 0 or 1)) +$(if $(filter-out 0 1,$($1)), $(error Unexpected value for parameter $1, expect either 0 or 1)) endef -# Usage: $(call uniq, ${LIST-OF-WORDS}) +# Usage: $(call uniq, $(LIST-OF-WORDS)) define uniq $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1))) endef @@ -58,39 +58,39 @@ _dim := \e[2m define print_header @printf "________________________________________" @printf "________________________________________\n" - @printf ":: %s\n" ${1} + @printf ":: %s\n" $(1) endef # Usage: $(call print_help_section, SECTION-TITLE) define print_help_section - @printf "%s:\n" ${1} + @printf "%s:\n" $(1) endef # Usage: $(call print_help_subsection, SUBSECTION-TITLE) define print_help_subsection - @printf " %s:\n" ${1} + @printf " %s:\n" $(1) endef # Usage: $(call print_help_target, TARGET-NAME, HELP-DESCRIPTION, HELP-CATEGORY) define print_help_target - @printf " ${_blu}% -21s${_rst} % -45b ${_dim}%s${_rst}\n" ${1} ${2} ${3} + @printf " $(_blu)% -21s$(_rst) % -45b $(_dim)%s$(_rst)\n" $(1) $(2) $(3) endef # Usage: $(call print_help_option, VAR-NAME, VAR-DEFAULT, DESCRIPTION) define print_help_option - @printf " % -36s %b\n" $(shell printf "${_grn}%s${_rst}=${_dim}%s${_rst}" ${1} ${2}) ${3} + @printf " % -36s %b\n" $(shell printf "$(_grn)%s$(_rst)=$(_dim)%s$(_rst)" $(1) $(2)) $(3) endef -# Usage: $(call print_help_define, VAR-NAME, ${VAR-NAME}) +# Usage: $(call print_help_define, VAR-NAME, $(VAR-NAME)) define print_help_define - @printf " ${_grn}%s${_rst}=${_dim}%s${_rst}\n" ${1} ${2} + @printf " $(_grn)%s$(_rst)=$(_dim)%s$(_rst)\n" $(1) $(2) endef define print_help_define_align - @printf " ${_grn}%-16s${_rst}=${_dim} %s${_rst}\n" ${1} ${2} + @printf " $(_grn)%-16s$(_rst)=$(_dim) %s$(_rst)\n" $(1) $(2) endef -# Usage: $(call print_help_define_lines, VAR-NAME, ${VAR-NAME}) +# Usage: $(call print_help_define_lines, VAR-NAME, $(VAR-NAME)) # # For example, given a call with the following: # @@ -103,16 +103,16 @@ endef # 20.04 # 22.04 # -# If the contents of ${VAR-NAME} is empty or only contains whitespace, +# If the contents of $(VAR-NAME) is empty or only contains whitespace, # then no extra newline is printed, and it behaves as print_help_define. define print_help_define_lines - @printf " ${_grn}%s${_rst}=${_dim}" ${1} - @if [ -n "$(strip ${2})" ]; then printf "\\ \n"; fi - @printf "%s" "$$(echo " ${2}" | fmt -5)" - @printf "${_rst}\n" + @printf " $(_grn)%s$(_rst)=$(_dim)" $(1) + @if [ -n "$(strip $(2))" ]; then printf "\\ \n"; fi + @printf "%s" "$$(echo " $(2)" | fmt -5)" + @printf "$(_rst)\n" endef -# Usage: $(call print_help_args_lines, VAR-NAME, ${VAR-NAME}) +# Usage: $(call print_help_args_lines, VAR-NAME, $(VAR-NAME)) # # This function behaves as print_help_define_lines, except that # it doesn't split on words, but on arguments. Each argument (leading with -) @@ -129,12 +129,12 @@ endef # --rm # --network host # -# If the contents of ${VAR-NAME} is empty, same behavior as print_help_define. +# If the contents of $(VAR-NAME) is empty, same behavior as print_help_define. define print_help_args_lines - @printf " ${_grn}%s${_rst}=${_dim}" ${1} - @if [ -n "$(strip ${2})" ]; then printf "\\ \n"; fi - @printf "%s" "$$(echo " ${2}" | sed -r -e 's/\W--?[^-]/\n \0/g' -e 's/^\s*\n//')" - @printf "${_rst}\n" + @printf " $(_grn)%s$(_rst)=$(_dim)" $(1) + @if [ -n "$(strip $(2))" ]; then printf "\\ \n"; fi + @printf "%s" "$$(echo " $(2)" | sed -r -e 's/\W--?[^-]/\n \0/g' -e 's/^\s*\n//')" + @printf "$(_rst)\n" endef # Usage: $(call print_help_usage) @@ -142,5 +142,5 @@ endef # This should be called only once, before all other print_help_* calls, # so that the help message starts with a usage statement. define print_help_usage - @printf "Usage: make ${_blu}target${_rst}\n" + @printf "Usage: make $(_blu)target$(_rst)\n" endef diff --git a/Makefile.package b/Makefile.package index 8d94a9372..d96a069a0 100644 --- a/Makefile.package +++ b/Makefile.package @@ -20,35 +20,35 @@ # You should also adjust the PACKAGE_CHANNEL variable. # -PROJECT_ROOT := $(dir $(abspath $(lastword ${MAKEFILE_LIST}))) -PROJECT_VERSION := $(shell [ -r ${PROJECT_ROOT}/VERSION ] && cat ${PROJECT_ROOT}/VERSION || echo unknown) +PROJECT_ROOT := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +PROJECT_VERSION := $(shell [ -r $(PROJECT_ROOT)/VERSION ] && cat $(PROJECT_ROOT)/VERSION || echo unknown) -include ${PROJECT_ROOT}/Makefile.help +include $(PROJECT_ROOT)/Makefile.help # Command for cloe-launch. # # This definition could be `cloe-launch`, but then you wouldn't get the # version of cloe-launch that is from this repository, but one that is # available globally. -CLOE_LAUNCH := PYTHONPATH="${PROJECT_ROOT}/cli" python3 -m cloe_launch +CLOE_LAUNCH := PYTHONPATH="$(PROJECT_ROOT)/cli" python3 -m cloe_launch SHELL := /bin/bash DATE := $(shell date +"%Y%m%d") TIMESTAMP := $(shell date -u +'%Y-%m-%dT%H:%M:%SZ') # Check if we are in a Git repository and try to describe the current -# state if we are. This is used for setting the ${PACKAGE_VERSION} if -# it is not set in conanfile or by ${PROJECT_VERSION}. -HAS_GIT := $(shell [ -e ${PROJECT_ROOT}/.git ] && echo "true") -ifeq (${PROJECT_VERSION},unknown) -ifeq (${HAS_GIT},true) +# state if we are. This is used for setting the $(PACKAGE_VERSION) if +# it is not set in conanfile or by $(PROJECT_VERSION). +HAS_GIT := $(shell [ -e $(PROJECT_ROOT)/.git ] && echo "true") +ifeq ($(PROJECT_VERSION),unknown) +ifeq ($(HAS_GIT),true) GIT_COMMIT_HASH := $(shell git log -1 --format=%h) GIT_COMMIT_DIRTY := $(shell git diff --quiet || echo "-dirty") GIT_DESCRIBE := $(shell git describe --dirty="-dirty" | sed -r "s/^v(.*)/\1/") else GIT_DESCRIBE := "unknown" endif -PROJECT_VERSION := ${GIT_DESCRIBE} +PROJECT_VERSION := $(GIT_DESCRIBE) endif # Default in-source directory. @@ -60,12 +60,12 @@ SOURCE_DIR := . # Don't change these unless you absolutely have to. SOURCE_CONANFILE := conanfile.py -SOURCE_CMAKELISTS:= ${SOURCE_DIR}/CMakeLists.txt +SOURCE_CMAKELISTS:= $(SOURCE_DIR)/CMakeLists.txt LOCKFILE_SOURCE := LOCKFILE_OPTION := -# When running `make clean`, delete the configured ${SOURCE_DIR}? +# When running `make clean`, delete the configured $(SOURCE_DIR)? # Anything other than `true` is taken to be false. CLEAN_SOURCE_DIR := false @@ -78,8 +78,8 @@ BUILD_IN_SOURCE := true BUILD_DIR := build # Don't change these unless you know what you are doing. -BUILD_CONANINFO := ${BUILD_DIR}/conanbuildinfo.txt -BUILD_LOCKFILE := ${BUILD_DIR}/conan.lock +BUILD_CONANINFO := $(BUILD_DIR)/conanbuildinfo.txt +BUILD_LOCKFILE := $(BUILD_DIR)/conan.lock # Default Conan build policy to use when installing Conan dependencies # as well as creating packages. See Conan documentation for possible values. @@ -94,19 +94,20 @@ BUILD_POLICY := outdated # # You probably want to override PACKAGE_CHANNEL, which is actually a USER/CHANNEL # combination. See your project for guidance on naming. -PACKAGE_NAME := $(shell sed -rn 's/.*name\s*=\s*"([^"]+)"$$/\1/p' ${SOURCE_CONANFILE}) +PACKAGE_NAME := $(shell sed -rn 's/.*name\s*=\s*"([^"]+)"$$/\1/p' $(SOURCE_CONANFILE)) PACKAGE_VERSION := $(or \ - $(shell sed -rn 's/\s+version\s*=\s*"([^"]+)"$$/\1/p' ${SOURCE_CONANFILE}), \ - ${PROJECT_VERSION}, \ + $(shell sed -rn 's/\s+version\s*=\s*"([^"]+)"$$/\1/p' $(SOURCE_CONANFILE)), \ + $(PROJECT_VERSION), \ unknown \ ) PACKAGE_CHANNEL := cloe/develop -PACKAGE_FQN := ${PACKAGE_NAME}/${PACKAGE_VERSION}@${PACKAGE_CHANNEL} +PACKAGE_FQN := $(PACKAGE_NAME)/$(PACKAGE_VERSION)@$(PACKAGE_CHANNEL) # Which files to consider as smoketest profiles when running targets # `smoketest-deps` and `smoketest`. This can be useful to override from the # command line if you just want to test one configuration. TEST_CONANFILES := tests/conanfile_*.py +TEST_DIR := tests # It is an order of magnitude faster to parse ~/.conan/editable_packages.json # ourselves than to get conan to do it for us. This should only take us 20ms, @@ -114,16 +115,16 @@ TEST_CONANFILES := tests/conanfile_*.py # or the path to the current conanfile.py is marked as editable. This helps # inform the user when they make a package editable, but then check out another # state of the tree with a different version. -SOURCE_CONANFILE_REALPATH := $(realpath ${SOURCE_CONANFILE}) +SOURCE_CONANFILE_REALPATH := $(realpath $(SOURCE_CONANFILE)) define JQ_PACKAGE_EDITABLE - if has(\"${PACKAGE_FQN}\") then - if .[\"${PACKAGE_FQN}\"].path == \"${SOURCE_CONANFILE_REALPATH}\" then + if has(\"$(PACKAGE_FQN)\") then + if .[\"$(PACKAGE_FQN)\"].path == \"$(SOURCE_CONANFILE_REALPATH)\" then \"editable\" else \"editable-elsewhere\" end else - if ([.[].path] | any(. == \"${SOURCE_CONANFILE_REALPATH}\")) then + if ([.[].path] | any(. == \"$(SOURCE_CONANFILE_REALPATH)\")) then \"editable-other-name\" else \"not-editable\" @@ -131,14 +132,18 @@ define JQ_PACKAGE_EDITABLE end endef +PACKAGE_EDITABLE := $(shell [ -e ~/.conan/editable_packages.json ] \ + && jq -r "$(JQ_PACKAGE_EDITABLE)" ~/.conan/editable_packages.json \ + || echo "not-editable") + # Normally, you should set this in your profile, but if you just want to build # the package in debug mode once, you can do it this way, although it will # only apply to local builds. # # This can be one of: None, Debug, Release, RelWithDebInfo, MinSizeRel BUILD_TYPE := -ifneq "${BUILD_TYPE}" "" -BUILD_TYPE_OPTION := -s ${PACKAGE_NAME}:build_type=${BUILD_TYPE} +ifneq "$(BUILD_TYPE)" "" +BUILD_TYPE_OPTION := -s $(PACKAGE_NAME):build_type=$(BUILD_TYPE) else BUILD_TYPE_OPTION := endif @@ -146,36 +151,36 @@ endif # These options can be set to influence package and configure. CONAN_OPTIONS := -ifneq "${LOCKFILE_SOURCE}" "" -.PHONY: ${BUILD_LOCKFILE} -ifeq "$(realpath ${LOCKFILE_SOURCE})" "$(realpath ${SOURCE_CONANFILE})" -$(error "LOCKFILE_SOURCE must contain superset of SOURCE_CONANFILE package and dependencies") -endif -LOCKFILE_OPTION := --lockfile="${BUILD_LOCKFILE}" -override CONAN_OPTIONS := -${BUILD_LOCKFILE}: ${LOCKFILE_SOURCE} export - # Create lockfile from LOCKFILE_SOURCE. - # - mkdir -p "${BUILD_DIR}" - conan lock create --lockfile-out "${BUILD_LOCKFILE}" ${BUILD_TYPE_OPTION} ${CONAN_OPTIONS} --build -- "${LOCKFILE_SOURCE}" >/dev/null +ifneq "$(LOCKFILE_SOURCE)" "" +LOCKFILE_OPTION := --lockfile="$(BUILD_LOCKFILE)" + +.PHONY: $(BUILD_LOCKFILE) +# Create lockfile from LOCKFILE_SOURCE. +# +$(BUILD_LOCKFILE): $(LOCKFILE_SOURCE) export + mkdir -p "$(BUILD_DIR)" + conan lock create --lockfile-out "$(BUILD_LOCKFILE)" $(BUILD_TYPE_OPTION) $(CONAN_OPTIONS) --build -- "$(LOCKFILE_SOURCE)" >/dev/null else # Lockfile will be created automatically by conan install command. -${BUILD_LOCKFILE}: +$(BUILD_LOCKFILE): endif # When using a --lockfile option, we cannot use profile, settings, options, env # or conf 'host' Conan options. -ifneq "${LOCKFILE_OPTION}" "" -ALL_OPTIONS := ${LOCKFILE_OPTION} ${CONAN_OPTIONS} +ifneq "$(LOCKFILE_OPTION)" "" +ALL_OPTIONS := $(LOCKFILE_OPTION) $(CONAN_OPTIONS) else -ALL_OPTIONS := ${BUILD_TYPE_OPTION} ${CONAN_OPTIONS} +ALL_OPTIONS := $(BUILD_TYPE_OPTION) $(CONAN_OPTIONS) endif # INFORMATIONAL TARGETS ------------------------------------------------------- .DEFAULT_GOAL := help .SILENT: help .PHONY: help -help:: parse-info parse-editable +help:: parse-info + +ifneq ($(DISABLE_HELP_PREAMBLE), true) +help:: $(call print_help_usage) echo echo "The following targets define common operations with this package in" @@ -183,6 +188,9 @@ help:: parse-info parse-editable echo $(call print_help_section, "Available targets") $(call print_help_target, help, "show this help") +endif + +help:: $(call print_help_target, status, "show status of package") $(call print_help_target, info, "show detailed package info") $(call print_help_target, smoketest-deps, "build smoketest dependencies for package") @@ -191,12 +199,10 @@ help:: parse-info parse-editable $(call print_help_target, export, "export recipe and sources", "[conan-cache]") $(call print_help_target, download, "download or create package", "[conan-cache]") $(call print_help_target, package, "create package with build policy", "[conan-cache]") - $(call print_help_target, package-all, "create package and dependencies", "[conan-cache]") - $(call print_help_target, package-outdated, "create package if outdated", "[conan-cache]") $(call print_help_target, list, "list installed package files", "[conan-cache]") $(call print_help_target, purge, "remove package from cache", "[conan-cache]") echo -ifeq (${BUILD_IN_SOURCE}, true) +ifeq ($(BUILD_IN_SOURCE), true) $(call print_help_target, editable, "instruct Conan to use in-source build") $(call print_help_target, uneditable, "instruct Conan to use local cache") echo @@ -204,7 +210,7 @@ ifeq (${BUILD_IN_SOURCE}, true) $(call print_help_target, configure, "install dependencies and configure package", "[in-source]") $(call print_help_target, test, "run CMake tests if they are available", "[in-source]") $(call print_help_target, export-pkg, "export build artifacts to Conan cache", "[in-source]") -ifeq (${CLEAN_SOURCE_DIR}, true) +ifeq ($(CLEAN_SOURCE_DIR), true) $(call print_help_target, clean, "remove source and build directories", "[in-source]") else $(call print_help_target, clean, "remove build directory", "[in-source]") @@ -212,49 +218,44 @@ endif echo endif $(call print_help_subsection, "Configuration") - $(call print_help_define_align, LOCKFILE_SOURCE, ${LOCKFILE_SOURCE}) -ifeq (${BUILD_IN_SOURCE}, true) - $(call print_help_define_align, SOURCE_DIR, ${SOURCE_DIR}) + $(call print_help_define_align, LOCKFILE_SOURCE, "$(LOCKFILE_SOURCE)") +ifeq ($(BUILD_IN_SOURCE), true) + $(call print_help_define_align, SOURCE_DIR, "$(SOURCE_DIR)") endif - $(call print_help_define_align, BUILD_DIR, ${BUILD_DIR}) - $(call print_help_define_align, BUILD_POLICY, ${BUILD_POLICY}) - $(call print_help_define_align, BUILD_TYPE, ${BUILD_TYPE}) - $(call print_help_define_align, CONAN_OPTIONS, ${CONAN_OPTIONS}) + $(call print_help_define_align, BUILD_DIR, "$(BUILD_DIR)") + $(call print_help_define_align, BUILD_POLICY, "$(BUILD_POLICY)") + $(call print_help_define_align, BUILD_TYPE, "$(BUILD_TYPE)") + $(call print_help_define_align, CONAN_OPTIONS, "$(CONAN_OPTIONS)") echo $(call print_help_subsection, "Package information") - $(call print_help_define_align, PACKAGE_NAME, ${PACKAGE_NAME}) - $(call print_help_define_align, PACKAGE_VERSION, ${PACKAGE_VERSION}) - $(call print_help_define_align, PACKAGE_CHANNEL, ${PACKAGE_CHANNEL}) - $(call print_help_define_align, PACKAGE_FQN, ${PACKAGE_FQN}) - $(call print_help_define_align, PACKAGE_EDITABLE,${PACKAGE_EDITABLE}) - $(call print_help_define_align, PACKAGE_ID, ${PACKAGE_ID}) - $(call print_help_define_align, PACKAGE_DIR, ${PACKAGE_DIR}) - $(call print_help_define_align, PACKAGE_DATE, ${PACKAGE_DATE}) - $(call print_help_define_align, GIT_COMMIT_HASH, ${GIT_COMMIT_HASH}) + $(call print_help_define_align, PACKAGE_NAME, "$(PACKAGE_NAME)") + $(call print_help_define_align, PACKAGE_VERSION, "$(PACKAGE_VERSION)") + $(call print_help_define_align, PACKAGE_CHANNEL, "$(PACKAGE_CHANNEL)") + $(call print_help_define_align, PACKAGE_FQN, "$(PACKAGE_FQN)") + $(call print_help_define_align, PACKAGE_EDITABLE,"$(PACKAGE_EDITABLE)") + $(call print_help_define_align, PACKAGE_ID, "$(PACKAGE_ID)") + $(call print_help_define_align, PACKAGE_DIR, "$(PACKAGE_DIR)") + $(call print_help_define_align, PACKAGE_DATE, "$(PACKAGE_DATE)") + $(call print_help_define_align, GIT_COMMIT_HASH, "$(GIT_COMMIT_HASH)") echo .PHONY: parse-info .SILENT: parse-info -parse-info: ${BUILD_LOCKFILE} +parse-info: $(BUILD_LOCKFILE) # Fetch package information from Conan. # # This command takes long, so we won't run it by default. Instead, if any # target needs one of these variables, they should depend on this target # to ensure that these variables are set. # - $(eval PACKAGE_INFO := $(shell CONAN_REQUEST_TIMEOUT=0.1 conan info ${ALL_OPTIONS} "${PACKAGE_FQN}" --package-filter "${PACKAGE_FQN}" --paths 2>/dev/null | sed -r 's/$$/\\n/')) - $(eval PACKAGE_ID := $(shell echo -e "${PACKAGE_INFO}" | sed -rn 's/^ *ID: *(.*)$$/\1/p')) - $(eval PACKAGE_DIR := $(shell echo -e "${PACKAGE_INFO}" | sed -rn 's/^ *package_folder: *(.*)$$/\1/p')) - $(eval PACKAGE_DATE := $(shell echo -e "${PACKAGE_INFO}" | sed -rn 's/^ *Creation date: *(.*)$$/\1/p')) - -.PHONY: parse-editable -.SILENT: parse-editable -parse-editable: - $(eval PACKAGE_EDITABLE := $(shell [ -e ~/.conan/editable_packages.json ] && jq -r "${JQ_PACKAGE_EDITABLE}" ~/.conan/editable_packages.json || echo "not-editable")) + $(eval PACKAGE_INFO := $(shell CONAN_REQUEST_TIMEOUT=0.1 conan info $(ALL_OPTIONS) "$(PACKAGE_FQN)" --package-filter "$(PACKAGE_FQN)" --paths 2>/dev/null | sed -r 's/$$/\\n/')) + $(eval PACKAGE_ID := $(shell echo -e "$(PACKAGE_INFO)" | sed -rn 's/^ *ID: *(.*)$$/\1/p')) + $(eval PACKAGE_DIR := $(shell echo -e "$(PACKAGE_INFO)" | sed -rn 's/^ *package_folder: *(.*)$$/\1/p')) + $(eval PACKAGE_DATE := $(shell echo -e "$(PACKAGE_INFO)" | sed -rn 's/^ *Creation date: *(.*)$$/\1/p')) .PHONY: status .SILENT: status -status: parse-info parse-editable +status: parse-info # Show the *approximate* status of each package in the cloe workspace. # # This lets you know whether a package is in editable mode or not, @@ -262,61 +263,62 @@ status: parse-info parse-editable # directory has been modified more recently than the package in the # Conan cache. # - if [ "${PACKAGE_EDITABLE}" != "not-editable" ] ; then \ - echo "${PACKAGE_EDITABLE} : ${PACKAGE_FQN}"; \ + if [ "$(PACKAGE_EDITABLE)" != "not-editable" ] ; then \ + echo "$(PACKAGE_EDITABLE) : $(PACKAGE_FQN)"; \ else \ - if [ -n "${PACKAGE_DATE}" ] && [ -z "$$(find -type f -newermt "${PACKAGE_DATE}")" ]; then \ - echo "ok : ${PACKAGE_FQN}"; \ + if [ -n "$(PACKAGE_DATE)" ] && [ -z "$$(find -type f -newermt "$(PACKAGE_DATE)")" ]; then \ + echo "ok : $(PACKAGE_FQN)"; \ else \ - echo "outdated : ${PACKAGE_FQN}"; \ + echo "outdated : $(PACKAGE_FQN)"; \ fi \ fi .PHONY: info-name .SILENT: info-name info-name: - echo ${PACKAGE_NAME} + echo $(PACKAGE_NAME) .PHONY: info-version .SILENT: info-version info-version: - echo ${PACKAGE_VERSION} + echo $(PACKAGE_VERSION) .PHONY: info-channel .SILENT: info-channel info-channel: - echo ${PACKAGE_CHANNEL} + echo $(PACKAGE_CHANNEL) .PHONY: info-fqn .SILENT: info-fqn info-fqn: - echo ${PACKAGE_FQN} + echo $(PACKAGE_FQN) .PHONY: info .SILENT: info info: parse-info - if [ -z "${PACKAGE_INFO}" ]; then \ + if [ -z "$(PACKAGE_INFO)" ]; then \ echo "Errors occurred, no output available."; \ else \ - echo ${PACKAGE_INFO}; \ + echo $(PACKAGE_INFO); \ fi .PHONY: smoketest smoketest: # Ensure that you have built all smoketest dependencies! - @for conanfile in ${TEST_CONANFILES}; do \ + @for conanfile in $(TEST_CONANFILES); do \ test -f "$${conanfile}" || continue; \ printf "Running BATS tests with conanfile: $${conanfile}\n\n"; \ - SHELL=/bin/bash ${CLOE_LAUNCH} shell "$${conanfile}" ${CONAN_OPTIONS} -- -c "source ${PROJECT_ROOT}/tests/setup_testname.bash; bats tests"; \ + SHELL=/bin/bash $(CLOE_LAUNCH) shell "$${conanfile}" $(CONAN_OPTIONS) -- \ + -c "source $(PROJECT_ROOT)/tests/setup_testname.bash; bats $(TEST_DIR)"; \ done .PHONY: smoketest-deps smoketest-deps: # Ensure that you have exported all relevant packages! - @for conanfile in ${TEST_CONANFILES}; do \ + @for conanfile in $(TEST_CONANFILES); do \ test -f "$${conanfile}" || continue; \ echo "Building dependencies for conanfile: $${conanfile}"; \ - ${CLOE_LAUNCH} prepare "$${conanfile}" ${CONAN_OPTIONS} || break; \ + $(CLOE_LAUNCH) prepare "$${conanfile}" $(CONAN_OPTIONS) || exit 1; \ done # CONFIGURATION TARGETS ------------------------------------------------------- @@ -331,7 +333,7 @@ editable: # # Run `make uneditable` to leave this mode. # - conan editable add . ${PACKAGE_FQN} + conan editable add $(SOURCE_CONANFILE) $(PACKAGE_FQN) .PHONY: uneditable uneditable: @@ -340,17 +342,24 @@ uneditable: # In uneditable mode, Conan will use the package within the Conan cache # (normally located in ~/.conan/data). This is the default behavior. # - conan editable remove ${PACKAGE_FQN} + conan editable remove $(PACKAGE_FQN) # CONAN TARGETS --------------------------------------------------------------- +.PHONY: lockfile +lockfile: $(BUILD_LOCKFILE) + .PHONY: export -export: parse-editable +export: +ifneq (,$(filter $(PACKAGE_EDITABLE),not-editable editable-other-name)) # Export sources to Conan cache. # # This does not build this package but provides the sources and the # build recipe to Conan for on-demand building. # - if [ "${PACKAGE_EDITABLE}" = "not-editable" ] || [ "${PACKAGE_EDITABLE}" = "editable-other-name" ]; then conan export . ${PACKAGE_FQN}; fi + conan export $(SOURCE_CONANFILE) $(PACKAGE_FQN) +else + # Export sources to Conan cache: skipped (package is $(PACKAGE_EDITABLE)) +endif .PHONY: download download: @@ -364,11 +373,11 @@ download: # # See: https://docs.conan.io/en/latest/mastering/policies.html # - conan create . ${PACKAGE_FQN} --build=never ${ALL_OPTIONS} || \ - conan create . ${PACKAGE_FQN} --build=${BUILD_POLICY} --build=${PACKAGE_NAME} ${ALL_OPTIONS} + conan create $(SOURCE_CONANFILE) $(PACKAGE_FQN) --build=never $(ALL_OPTIONS) || \ + conan create $(SOURCE_CONANFILE) $(PACKAGE_FQN) --build=$(BUILD_POLICY) --build=$(PACKAGE_NAME) $(ALL_OPTIONS) .PHONY: package -package: ${BUILD_LOCKFILE} +package: $(BUILD_LOCKFILE) # Build the package in Conan cache unconditionally. # # Conan will retrieve and build all dependencies based on the build policy. @@ -376,27 +385,8 @@ package: ${BUILD_LOCKFILE} # # See: https://docs.conan.io/en/latest/mastering/policies.html # - conan create . ${PACKAGE_FQN} \ - --build=${BUILD_POLICY} --build=${PACKAGE_NAME} ${ALL_OPTIONS} - -.PHONY: package-all -package-all: ${BUILD_LOCKFILE} - # Build the package in Conan cache unconditionally. - # - # Conan will retrieve and build all dependencies unconditionally. - # Note that this cannot be called if the package is currently in editable mode. - # - conan create . ${PACKAGE_FQN} --build ${ALL_OPTIONS} - -.PHONY: package-outdated -package-outdated: ${BUILD_LOCKFILE} - # Build the package in Conan cache if it is outdated. - # - # Note that this does not take dependencies of ${PACKAGE_NAME} into account. - # Rebuilds will occur if package info has changed or a hash of the source - # code changes. Timestamps are not taken into account. - # - conan create . ${PACKAGE_FQN} --build=outdated ${ALL_OPTIONS} + conan create $(SOURCE_CONANFILE) $(PACKAGE_FQN) \ + --build=$(BUILD_POLICY) --build=$(PACKAGE_NAME) $(ALL_OPTIONS) .PHONY: purge purge: @@ -406,43 +396,39 @@ purge: # has the same ID. Purging all instances is useful for forcing a rebuild # of all instances of this package henceforth. # - -conan remove -f ${PACKAGE_FQN} + -conan remove -f $(PACKAGE_FQN) .PHONY: list list: parse-info # List all files in the Conan cache package directory. # - @tree ${PACKAGE_DIR} + @tree $(PACKAGE_DIR) # IN-SOURCE TARGETS ----------------------------------------------------------- .PHONY: clean clean: # Clean the build directory and Python cache files. # - rm -rf "${BUILD_DIR}" - rm -rf __pycache__ - rm -f CMakeUserPresets.json - rm -f compile_commands.json - rm -f graph_info.json -ifeq (${CLEAN_SOURCE_DIR}, true) - [ "${SOURCE_DIR}" != "." ] && rm -rf "${SOURCE_DIR}" + rm -rf "$(BUILD_DIR)" __pycache__ CMakeUserPresets.json compile_commands.json graph_info.json +ifeq ($(CLEAN_SOURCE_DIR), true) + [ "$(SOURCE_DIR)" != "." ] && rm -rf "$(SOURCE_DIR)" endif -ifeq (${BUILD_IN_SOURCE}, false) +ifeq ($(BUILD_IN_SOURCE), false) .PHONY: all configure test export-pkg -all configure test export-pkg ${SOURCE_DIR} ${SOURCE_CMAKELISTS} ${BUILD_CONANINFO}: +all configure test export-pkg $(SOURCE_DIR) $(SOURCE_CMAKELISTS) $(BUILD_CONANINFO): @echo "Error: [in-source] targets are not supported for this package." @echo "Note: please use [conan-cache] targets, such as 'package'." exit 1 else .PHONY: all -all: ${BUILD_CONANINFO} | ${SOURCE_DIR} +all: $(BUILD_CONANINFO) | $(SOURCE_DIR) # Build the package in-source. # - conan build . --source-folder="${SOURCE_DIR}" --install-folder="${BUILD_DIR}" + conan build $(SOURCE_CONANFILE) --source-folder="$(SOURCE_DIR)" --install-folder="$(BUILD_DIR)" .PHONY: configure -configure: ${BUILD_CONANINFO} +configure: $(BUILD_CONANINFO) ln -rsf "$$(dirname $$(dirname $$(jq -r '.include[0]' CMakeUserPresets.json)))/compile_commands.json" .PHONY: test @@ -451,8 +437,8 @@ test: # # If no tests are available, this will simply return true. # - @if [ -f "${BUILD_DIR}"/CTestTestfile.cmake ]; then \ - cd "${BUILD_DIR}" && ctest; \ + @if [ -f "$(BUILD_DIR)"/CTestTestfile.cmake ]; then \ + cd "$(BUILD_DIR)" && ctest; \ else \ true; \ fi @@ -467,24 +453,24 @@ export-pkg: # # Note that this does not require the package to be editable. # - conan export-pkg . ${PACKAGE_FQN} --build-folder="${BUILD_DIR}" + conan export-pkg $(SOURCE_CONANFILE) $(PACKAGE_FQN) --build-folder="$(BUILD_DIR)" -${SOURCE_DIR}: +$(SOURCE_DIR): # Copy source to an external source directory. # # This usually isn't necessary, and should not be called when # SOURCE_DIR is identical to the current directory. # - [ "$(shell readlink -f "${SOURCE_DIR}")" != "$(shell readlink -f .)" ] - conan source . --source-folder="${SOURCE_DIR}" + [ "$(shell readlink -f "$(SOURCE_DIR)")" != "$(shell readlink -f .)" ] + conan source $(SOURCE_CONANFILE) --source-folder="$(SOURCE_DIR)" -${SOURCE_CMAKELISTS}: | ${SOURCE_DIR} +$(SOURCE_CMAKELISTS): | $(SOURCE_DIR) -${BUILD_CONANINFO}: ${SOURCE_CONANFILE} ${BUILD_LOCKFILE} ${SOURCE_CMAKELISTS} +$(BUILD_CONANINFO): $(SOURCE_CONANFILE) $(BUILD_LOCKFILE) $(SOURCE_CMAKELISTS) # Install package dependencies and configure in-source build. # - mkdir -p "${BUILD_DIR}" - conan install . ${PACKAGE_FQN} --install-folder="${BUILD_DIR}" --build=${BUILD_POLICY} ${ALL_OPTIONS} - conan build --configure . --source-folder="${SOURCE_DIR}" --install-folder="${BUILD_DIR}" - touch ${BUILD_CONANINFO} + mkdir -p "$(BUILD_DIR)" + conan install $(SOURCE_CONANFILE) $(PACKAGE_FQN) --install-folder="$(BUILD_DIR)" --build=$(BUILD_POLICY) $(ALL_OPTIONS) + conan build --configure $(SOURCE_CONANFILE) --source-folder="$(SOURCE_DIR)" --install-folder="$(BUILD_DIR)" + touch $(BUILD_CONANINFO) endif diff --git a/Makefile.setup b/Makefile.setup index d9ac0cb74..626d308d3 100644 --- a/Makefile.setup +++ b/Makefile.setup @@ -13,9 +13,9 @@ SHELL := /bin/bash PROJECT_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) CONAN_DIR := $(shell conan config home 2>/dev/null || echo "$HOME/.conan") CONAN_PROFILE := default -CONAN_PROFILE_PATH := ${CONAN_DIR}/profiles/${CONAN_PROFILE} +CONAN_PROFILE_PATH := $(CONAN_DIR)/profiles/$(CONAN_PROFILE) -include ${PROJECT_ROOT}/Makefile.help +include $(PROJECT_ROOT)/Makefile.help APT := $(or \ $(shell command -v apt 2>/dev/null), \ @@ -28,7 +28,7 @@ PIP := $(or \ $(shell command -v pip3 2>/dev/null), \ $(shell command -v pip 2>/dev/null) \ ) -ifeq (${VIRTUAL_ENV}, ) +ifeq ($(VIRTUAL_ENV), ) PIP_INSTALL_ARGS := --user --upgrade else PIP_INSTALL_ARGS := --upgrade @@ -37,8 +37,8 @@ endif PIPX := $(shell command -v pipx 2>/dev/null) PIPX_INSTALL_ARGS := ifndef PIPX -PIPX := ${PIP} -PIPX_INSTALL_ARGS := ${PIP_INSTALL_ARGS} +PIPX := $(PIP) +PIPX_INSTALL_ARGS := $(PIP_INSTALL_ARGS) endif .DEFAULT_GOAL := help @@ -49,9 +49,9 @@ help:: $(call print_help_target, setup-git, "perform Git repository setup") $(call print_help_target, setup-conan, "install Conan profile") $(call print_help_target, install-system-deps, "install build (and development) system requirements") - $(call print_help_target, install-python-deps, "install Python runtime requirements with ${_dim}${PIP}${_rst}") - $(call print_help_target, install-sphinx-deps, "install Sphinx runtime requirements with ${_dim}${PIP}${_rst}") - $(call print_help_target, install-python-tools, "install Python development tools with ${_dim}${PIPX}${_rst}") + $(call print_help_target, install-python-deps, "install Python runtime requirements with $(_dim)$(PIP)$(_rst)") + $(call print_help_target, install-sphinx-deps, "install Sphinx runtime requirements with $(_dim)$(PIP)$(_rst)") + $(call print_help_target, install-python-tools, "install Python development tools with $(_dim)$(PIPX)$(_rst)") echo .PHONY: setup-git @@ -61,17 +61,17 @@ setup-git: .PHONY: setup-conan setup-conan: # Install Conan if it is not available. - if ! command -v conan >/dev/null 2>&1; then ${PIP} install --user --upgrade "conan<2"; fi + if ! command -v conan >/dev/null 2>&1; then $(PIP) install --user --upgrade "conan<2"; fi # Initialize Conan configuration if it doesn't already exist. # - # Since running any conan command, even conan --help creates ${CONAN_DIR} + # Since running any conan command, even conan --help creates $(CONAN_DIR) # and the default configuration, we rely on the existence of the default # profile as an indication that we have a "fresh" setup where we can # make our override. - if [ ! -f ${CONAN_PROFILE_PATH} ]; then \ + if [ ! -f $(CONAN_PROFILE_PATH) ]; then \ conan config init; \ - conan profile update settings.compiler.libcxx=libstdc++11 ${CONAN_PROFILE}; \ - conan profile update settings.build_type=Debug ${CONAN_PROFILE}; \ + conan profile update settings.compiler.libcxx=libstdc++11 $(CONAN_PROFILE); \ + conan profile update settings.build_type=Debug $(CONAN_PROFILE); \ fi if ! conan config get general.default_build_profile >/dev/null 2>&1; then \ conan config set general.default_build_profile=default; \ @@ -80,15 +80,15 @@ setup-conan: conan config set general.revisions_enabled=True; \ fi # Install cloe-{debug,normal,release} profiles. - for profile in "${PROJECT_ROOT}"/dist/conan/*.profile; do \ + for profile in "$(PROJECT_ROOT)"/dist/conan/*.profile; do \ export profile_name=$$(basename -s .profile $${profile}); \ - install -m 644 "$${profile}" "${CONAN_DIR}/profiles/$${profile_name}"; \ - sed -r -i "s/default/${CONAN_PROFILE}/" "${CONAN_DIR}/profiles/$${profile_name}"; \ + install -m 644 "$${profile}" "$(CONAN_DIR)/profiles/$${profile_name}"; \ + sed -r -i "s/default/$(CONAN_PROFILE)/" "$(CONAN_DIR)/profiles/$${profile_name}"; \ done # Ensure we have an up-to-date CMake configured. if [ $$(( cmake --version | head -1 | cut -f3 -d' '; echo "3.14.99" ) | sort -V | tail -1) = "3.14.99" ]; then \ - if ! grep "cmake/" ${CONAN_PROFILE_PATH} >/dev/null; then \ - echo -e "[tool_requires]\ncmake/[>=3.15.0]" >> ${CONAN_PROFILE_PATH}; \ + if ! grep "cmake/" $(CONAN_PROFILE_PATH) >/dev/null; then \ + echo -e "[tool_requires]\ncmake/[>=3.15.0]" >> $(CONAN_PROFILE_PATH); \ fi; \ fi @@ -102,8 +102,8 @@ endif .PHONY: install-ubuntu-deps install-ubuntu-deps:: - command -v ${APT} >/dev/null 2>&1 - ${APT} install ${APT_ARGS} \ + command -v $(APT) >/dev/null 2>&1 + $(APT) install $(APT_ARGS) \ bats \ build-essential \ clang-format \ @@ -129,8 +129,8 @@ install-ubuntu-deps:: ; # Require GCC and G++ version >= 8 - if [ "${UBUNTU_VERSION}" == "18.04" ]; then \ - ${APT} install ${APT_ARGS} gcc-8 g++-8; \ + if [ "$(UBUNTU_VERSION)" == "18.04" ]; then \ + $(APT) install $(APT_ARGS) gcc-8 g++-8; \ if [ $$(readlink /usr/bin/g++) == "g++-7" ]; then \ ln -sf /usr/bin/g++-8 /usr/bin/g++ && \ ln -sf /usr/bin/gcc-8 /usr/bin/gcc; \ @@ -140,8 +140,8 @@ install-ubuntu-deps:: # Python ---------------------------------------------------------------------- .PHONY: install-python-deps install-python-deps:: - command -v ${PIP} >/dev/null 2>&1 - ${PIP} install ${PIP_INSTALL_ARGS} \ + command -v $(PIP) >/dev/null 2>&1 + $(PIP) install $(PIP_INSTALL_ARGS) \ click \ "conan<2.0.0" \ libtmux \ @@ -151,12 +151,12 @@ install-python-deps:: .PHONY: install-sphinx-deps install-sphinx-deps: - command -v ${PIP} >/dev/null 2>&1 - ${PIP} install ${PIP_INSTALL_ARGS} -r docs/requirements.txt + command -v $(PIP) >/dev/null 2>&1 + $(PIP) install $(PIP_INSTALL_ARGS) -r docs/requirements.txt .PHONY: install-python-tools install-python-tools:: - command -v ${PIPX} >/dev/null 2>&1 + command -v $(PIPX) >/dev/null 2>&1 for pkg in \ black \ mypy \ @@ -166,5 +166,5 @@ install-python-tools:: yq \ ; \ do \ - ${PIPX} install ${PIPX_INSTALL_ARGS} $${pkg}; \ + $(PIPX) install $(PIPX_INSTALL_ARGS) $${pkg}; \ done diff --git a/README.md b/README.md index c5bfc46ca..092c93472 100644 --- a/README.md +++ b/README.md @@ -84,14 +84,15 @@ See the Conan [documentation][6] for more information on how to do this. To build all packages, you should run the following: - make export-vendor package + make export-vendor export-all + make -C meta package This will export all Conan recipes from this repository and create the cloe package. Conan will download and build all necessary dependencies. Should any errors occur during the build, you may have to force Conan to build all packages instead of re-using packages it finds: ``` - make package CONAN_OPTIONS="--build" + make -C meta package CONAN_OPTIONS="--build" ``` Run `make help` to get an overview of the available targets we expect you to use. For more details on how this is done, have a look at the Makefiles in the @@ -166,7 +167,7 @@ Note that the above examples show the verbose output of the `cloe-launch` tool. Integration and system tests can be run to ensure that all the packages built are working together as expected: - make smoketest-deps + make export-all smoketest-deps make smoketest This will build packages in the required configurations as defined by the @@ -258,6 +259,42 @@ Note that this build requires the use of docker buildx, which has been available for some time. This allows us to mount secrets in at build time and also speeds up the build by the strategic use of caches. +Known Issues +------------ + +### Build-require 'protobuf' cannot be found in lockfile + +When using `build-all`, `cloe-osi` fails to build with: + + ERROR: Build-require 'protobuf' cannot be found in lockfile + +See the [upstream issue](https://github.com/conan-io/conan/issues/10544). +In Conan 1, a dependency in a lockfile is only in host or build context, not +both. Unfortunately, this is only fixed in Conan 2. + +The use-case for build-all is to build everything in editable mode. +For that, use the new super-build instead of building individual packages. + +### Superbuild 'cloe' package "provides the same functionality" error + +When using the `cloe` super-build package in tests, you may run into the +following error: + + ERROR: At least two recipes provides the same functionality: + - 'fable' provided by 'cloe/0.25.0@cloe/develop', 'fable/0.25.0@cloe/develop' + - 'cloe-runtime' provided by 'cloe/0.25.0@cloe/develop', 'cloe-runtime/0.25.0@cloe/develop' + - 'cloe-models' provided by 'cloe/0.25.0@cloe/develop', 'cloe-models/0.25.0@cloe/develop' + +This problem occurs when both `cloe` and one of the packages that `cloe` +*provides* are pulled in as dependencies. Ideally, Conan should then +use `cloe` instead, but it would appear that Conan, at least in v1, +is unable to do this. + +The `cloe` super-build package is primarily used for development purposes, +and until these kinks can be worked out, you should use the set of +individual packages for production. + + [1]: https://conan.io [2]: https://docs.microsoft.com/en-us/windows/wsl/about [3]: https://ubuntu.com diff --git a/conanfile.py b/conanfile.py index b1b17d121..25d52ad8a 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,7 +1,9 @@ # mypy: ignore-errors # pylint: skip-file +import os from pathlib import Path +from semver import SemVer from conan import ConanFile from conan.tools import cmake, files, scm @@ -13,22 +15,67 @@ class Cloe(ConanFile): name = "cloe" license = "Apache-2.0" url = "https://github.com/eclipse/cloe" - description = "Closed-loop automated driving simulation environment" + description = """ + Development package containing most cloe-* packages from the primary Eclipse repository. + + WARNING: + This package "provides" the cloe-* packages it contains, + but unfortunately this is NOT compatible with other packages that + require these. This is a severe limitation of Conan (v1). + + As such, this package should only be used for development purposes. + """ topics = ["simulation"] settings = "os", "compiler", "build_type", "arch" + provides = ( + "fable", + "cloe-runtime", + "cloe-models", + "cloe-oak", + "cloe-engine", + "cloe-plugin-basic", + "cloe-plugin-clothoid-fit", + "cloe-plugin-esmini", + "cloe-plugin-frustum-culling", + "cloe-plugin-gndtruth-extractor", + "cloe-plugin-minimator", + "cloe-plugin-mocks", + "cloe-plugin-noisy-sensor", + "cloe-plugin-speedometer", + "cloe-plugin-virtue", + "cloe-plugins-core", + ) options = { - "with_vtd": [True, False], + "shared": [True, False], + "fPIC": [True, False], + "fable_allow_comments": [True, False], + "engine_server": [True, False], "with_esmini": [True, False], - "with_engine": [True, False], + "with_vtd": [True, False], } default_options = { - "with_vtd": False, + "shared": True, + "fPIC": True, + "fable_allow_comments": True, + "engine_server": True, "with_esmini": True, - "with_engine": True, - - "cloe-engine:server": True, + "with_vtd": False, } + generators = "CMakeDeps", "VirtualRunEnv" no_copy_source = True + exports_sources = [ + "**/CMakeLists.txt", + "**/cmake/*", + "**/include/*", + "**/src/*", + "**/ui/*", + + "fable/examples/*", + + "engine/webui/*", + + "CMakelists.txt" + ] def set_version(self): version_file = Path(self.recipe_folder) / "VERSION" @@ -39,33 +86,123 @@ def set_version(self): self.version = git.run("describe --dirty=-dirty")[1:] def requirements(self): - def cloe_requires(dep): - self.requires(f"{dep}/{self.version}@cloe/develop") - - cloe_requires("cloe-runtime") - cloe_requires("cloe-models") - cloe_requires("cloe-plugin-basic") - cloe_requires("cloe-plugin-clothoid-fit") - cloe_requires("cloe-plugin-frustum-culling") - cloe_requires("cloe-plugin-gndtruth-extractor") - cloe_requires("cloe-plugin-minimator") - cloe_requires("cloe-plugin-mocks") - cloe_requires("cloe-plugin-noisy-sensor") - cloe_requires("cloe-plugin-speedometer") - cloe_requires("cloe-plugin-virtue") + self.requires("boost/1.74.0") + self.requires("cli11/2.3.2", private=True) + self.requires("eigen/3.4.0") + self.requires("fmt/9.1.0") + self.requires("incbin/cci.20211107"), + self.requires("inja/3.4.0") + self.requires("nlohmann_json/3.11.3") + self.requires("spdlog/1.11.0") + if self.options.engine_server: + self.requires("oatpp/1.3.0", private=True) if self.options.with_esmini: - cloe_requires("cloe-plugin-esmini") + self.requires("esmini/2.37.4@cloe/stable") if self.options.with_vtd: - cloe_requires("cloe-plugin-vtd") + self.requires("vtd-api/2022.3@cloe/stable", private=True) - boost_version = "1.74.0" - if self.options.with_engine: - cloe_requires("cloe-engine") - - # Overrides: self.requires("zlib/1.2.13", override=True) - self.requires("fmt/9.1.0", override=True) - self.requires("inja/3.4.0", override=True) - self.requires("nlohmann_json/3.11.2", override=True) - self.requires("incbin/cci.20211107", override=True), - self.requires(f"boost/{boost_version}", override=True) + + def build_requirements(self): + self.test_requires("gtest/1.14.0") + self.test_requires("sol2/3.3.0") + + def layout(self): + cmake.cmake_layout(self) + self.cpp.build.bindirs = ["bin"] + self.cpp.source.includedirs.append(os.path.join(self.folders.build, "include")) + + def generate(self): + # The version as a single 32-bit number takes the format: + # + # (EPOCH << 24) | (MAJOR_VERSION << 16) | (MINOR_VERSION << 8) | PATCH_VERSION + # + # Each version consists of at most 8 bits, so 256 potential values, including 0. + # The epoch starts with 0, and is bumped after each version naming scheme. + semver = SemVer(self.version, True) + version_u32 = (0<<24) | (semver.major << 16) | (semver.minor << 8) | semver.patch + + tc = cmake.CMakeToolchain(self) + tc.cache_variables["CMAKE_EXPORT_COMPILE_COMMANDS"] = True + tc.cache_variables["CMAKE_MODULE_PATH"] = self.source_folder + "/runtime/cmake" + tc.cache_variables["FABLE_VERSION"] = self.version + tc.cache_variables["FABLE_VERSION_U32"] = version_u32 + tc.cache_variables["FABLE_ALLOW_COMMENTS"] = self.options.fable_allow_comments + tc.cache_variables["CLOE_PROJECT_VERSION"] = self.version + tc.cache_variables["CLOE_VERSION"] = self.version + tc.cache_variables["CLOE_VERSION_U32"] = version_u32 + tc.cache_variables["CLOE_ENGINE_WITH_SERVER"] = self.options.engine_server + tc.cache_variables["CLOE_WITH_ESMINI"] = self.options.with_esmini + tc.cache_variables["CLOE_WITH_VTD"] = self.options.with_vtd + tc.generate() + + def build(self): + cm = cmake.CMake(self) + if self.should_configure: + cm.configure() + if self.should_build: + cm.build() + if self.should_test: + cm.test() + + def package(self): + if self.should_install: + cm = cmake.CMake(self) + cm.install() + + # Package license files for compliance + for meta, dep in self.dependencies.items(): + if dep.package_folder is None: + continue + ref = str(meta.ref) + name = ref[: str(ref).index("/")] + files.copy( + self, + "*", + src=os.path.join(dep.package_folder, "licenses"), + dst=os.path.join(self.package_folder, "licenses", name), + ) + + def package_info(self): + self.cpp_info.set_property("cmake_find_mode", "both") + self.cpp_info.set_property("cmake_file_name", "cloe") + self.cpp_info.set_property("pkg_config_name", "cloe") + + self.cpp_info.components["fable"].libs = ["fable"] + self.cpp_info.components["fable"].set_property("cmake_file_name", "fable") + self.cpp_info.components["fable"].set_property("cmake_target_name", "fable::fable") + self.cpp_info.components["fable"].set_property("pkg_config_name", "fable") + + self.cpp_info.components["runtime"].libs = ["cloe-runtime"] + self.cpp_info.components["runtime"].requires = ["fable"] + self.cpp_info.components["runtime"].set_property("cmake_file_name", "cloe-runtime") + self.cpp_info.components["runtime"].set_property("cmake_target_name", "cloe::runtime") + self.cpp_info.components["runtime"].set_property("pkg_config_name", "cloe-runtime") + + if self.settings.os == "Linux": + self.cpp_info.system_libs.append("pthread") + self.cpp_info.system_libs.append("dl") + + # Linking to libstdc++fs is required on GCC < 9. + # (GCC compilers with version < 7 have no std::filesystem support.) + # No consideration has been made yet for other compilers, + # please add them here as necessary. + if self.settings.get_safe("compiler") == "gcc" and self.settings.get_safe("compiler.version") in ["7", "8"]: + self.cpp_info.system_libs = ["stdc++fs"] + + self.cpp_info.libs = files.collect_libs(self) + if not self.in_local_cache: # editable build + self.cpp_info.builddirs.append(os.path.join(self.source_folder, "cmake")) + self.cpp_info.includedirs.append(os.path.join(self.build_folder, "include")) + bindir = os.path.join(self.build_folder, "bin") + libdir = os.path.join(self.build_folder, "lib"); + else: + self.cpp_info.builddirs.append(os.path.join("lib", "cmake", "cloe")) + bindir = os.path.join(self.package_folder, "bin") + libdir = None + + self.output.info(f"Appending PATH environment variable: {bindir}") + self.runenv_info.prepend_path("PATH", bindir) + if libdir is not None: + self.output.info(f"Appending LD_LIBRARY_PATH environment variable: {libdir}") + self.runenv_info.append_path("LD_LIBRARY_PATH", libdir) diff --git a/docs/develop/building-cloe.rst b/docs/develop/building-cloe.rst index e3c7989b4..bb64847fe 100644 --- a/docs/develop/building-cloe.rst +++ b/docs/develop/building-cloe.rst @@ -29,7 +29,7 @@ directory of every Cloe package (e.g. in ``plugins/basic/``): .. comment: The path below is relative to the project docs folder, not this file. - .. runcmd:: make -C ../models help + .. runcmd:: bash -c "make -C ../models help | sed -e 's/\x1b\[[0-9;]*m//g'" :replace: "PACKAGE_DIR:.*\\//PACKAGE_DIR: \\/" ``conanfile.py`` @@ -61,22 +61,56 @@ Verify that the cloe-plugin-basic package is currently in editable mode:: make status .. note:: - Positive-Example: + Positive-Example:: - .. code-block:: + editable : cloe-plugin-basic/0.18.0-rc5-3-g53c80db@cloe/develop - editable : cloe-plugin-basic/0.18.0-rc5-3-g53c80db@cloe/develop + Negative-Example:: - Negative-Example: - - .. code-block:: - - ok : cloe-plugin-basic/0.18.0-rc5-3-g53c80db@cloe/develop + ok : cloe-plugin-basic/0.18.0-rc5-3-g53c80db@cloe/develop Now, you can build the package binaries in your local working directory:: make clean all +The next time when Conan needs the package ``cloe-plugin-basic`` in +this version, it will resolve the include and library directories +to this local build. It is important to understand that you as a +developer are now responsible for ABI compatibility!! + +.. note:: + Conan can build packages with any constellation of dependencies that + you may require. This means that it is necessary to build an individual + package in a way that is compatible with the final composition. + + For example, it may be that the entire set of packages as defined by + the ``cloe-meta`` package require ``boost/1.65.1``. When building + the ``basic`` plugin as in this example, it has no way of knowing + that this version of Boost will be used when building ``cloe-engine``. + Therefore Conan will use the latest version of the ``boost`` package + it can find, such as ``boost/1.78.0``. + + In normal non-editable builds, Conan tracks these potential + incompatibilities and prevents you from incorrect combinations. + In editable mode however, you are responsible. Combining code + linked to two different versions of Boost is undefined behavior + and will lead to segfaults or worse! + + The solution to this dilemma is to let Conan know when making + a local build to use the final composition configuration for + resolving dependency configurations. This can be done by + generating a lockfile first of the final composition, and + using this lockfile when building a part locally. + + This is common enough that there is a simple mechanism baked + into the Makefiles to use a Conan recipe for automatically + generating and using a lockfile:: + + make clean all LOCKFILE_SOURCE=${CLOE_ROOT}/conanfile-meta.py + + where ``${CLOE_ROOT}`` is the path to the repository root; for + the ``basic`` plugin, this is ``../..``. + Since the package is in editable mode, the binaries will be created in the ``./build/`` directory in your package sub-directory. @@ -91,6 +125,105 @@ Verify the package status:: If you execute the latter command from the top-level directory, you will see the status of all Cloe packages. +Practical Example +""""""""""""""""" + +Let's apply the above to a very practical example involving ``cloe-engine``. +Assume the following situation: I checkout a develop branch, such as +``develop``, with the intention of modifying the ``cloe-engine`` package. + +First, because I am going to make changes, I disable the use of ``git describe`` +for versioning by explicitely setting a version:: + + echo "0.99.0-develop" > VERSION + +Then I make sure the entire project is exported:: + + make export-all + +.. note:: + This is roughtly equivalent to:: + + ( cd fable && conan export conanfile.py fable/0.99.0-develop@cloe/develop) + ( cd runtime && conan export conanfile.py cloe-runtime/0.99.0-develop@cloe/develop) + ... + +If there are any changes in other packages, I want to pick up those as well. +I let Conan know that I want to use ``cloe-engine`` in editable mode:: + + cd engine + make editable + +.. note:: + This is equivalent to:: + + cd engine + conan editable add conanfile cloe-engine/0.99.0-develop@cloe/develop + +TODO: This section + +Now, I need to choose a configuration that I want to use for testing the +entire set of packages. I can use a configuration in the ``tests/`` directory, +such as ``tests/conanfile_deployment.py``. +I use this when building ``cloe-engine`` as the source for creating a lockfile:: + + cd engine + make clean all LOCKFILE_SOURCE=../tests/conanfile_deployment.py + +This will automatically build any missing dependencies that are necessary for +building ``cloe-engine``, after which it will build ``cloe-engine`` locally. + +Before running any tests, I may need to make sure any additional dependencies +not required by ``cloe-engine`` but required for the test execution are +built:: + + cloe-launch prepare tests/conanfile_deployment.py + +.. note:: + This is *approximately* equivalent to:: + + conan install ../tests/conanfile_deployment.py --build=outdated --build=cascade + +Once this is complete, we can launch into a correctly configured shell, +with ``PATH`` and ``LD_LIBRARY_PATH`` set so that the shell can find +``cloe-engine`` and it can find required libraries and plugins. + +.. code-block:: + + cloe-launch shell -c tests/conanfile_deployment.py + +And at this point we are done and can run tests, make modifications +to the editable ``cloe-engine`` package, rebuild, and run tests again:: + + bats tests + $EDITOR engine/src/main.cpp + make -C engine all + bats tests + + +Superbuild +---------- + +The practical example of in-source builds above was one of the easiest +configurations we could choose. It becomes more arduous when we want to +edit packages that other packages in turn depend on, because then we need +to compile multiple packages by hand in the correct order. + +To side-step all of this, we have the ``cloe`` package, which is a +super-build of all other packages. + +You can build in the Conan cache with:: + + make package + +You can build it locally with:: + + make all + +You can then launch a virtual environment with ``cloe-launch``:: + + make editable + cloe-launch shell tests/conanfile_superbuild.py .. _Conan local cache: https://docs.conan.io/en/latest/mastering/custom_cache.html .. _Conan CMake integration: https://docs.conan.io/en/latest/integrations/build_system/cmake.html diff --git a/docs/install.rst b/docs/install.rst index 8d0dc5442..39cd6e4dd 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -69,14 +69,15 @@ Build Cloe Packages ------------------- To build all packages, you should run the following:: - make export-vendor package + make export-vendor export-all + make -C meta package This will export all Conan recipes from this repository and create the cloe package. Conan will download and build all necessary dependencies. Should any errors occur during the build, you may have to force Conan to build all packages instead of re-using packages it finds:: - make package CONAN_OPTIONS="--build" + make -C meta package CONAN_OPTIONS="--build" .. note:: Depending on your Conan profile, building the Cloe packages can involve @@ -88,16 +89,16 @@ all packages instead of re-using packages it finds:: If you like, you can inspect what a Conan Cloe package looks like by browsing the Conan cache directory under ``~/.conan/data/cloe``. -Run ``make help`` to get an overview of the available targets we expect you to -use. For more details on how this is done, have a look at the Makefiles in the -repository root. +Run ``make help`` to get an overview of the available targets we anticipate you +may want to use. For more details on how this is done, have a look at the +Makefiles in the repository root. Run System Tests ---------------- To check that everything is working as it should, we recommend you run the included test suite once before commencing with anything else:: - make export export-vendor smoketest-deps smoketest + make export-vendor export-all smoketest-deps smoketest .. _Conan: https://conan.io .. _Conan documentation: https://docs.conan.io/en/latest/ diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index ff3e0ad5b..abf653f82 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -1,18 +1,17 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_engine LANGUAGES CXX) -set(target cloe-engine) -set(output cloe-engine) -set(libstack cloe-stack) - -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) -find_package(fable REQUIRED) -find_package(Boost REQUIRED) -find_package(CLI11 REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(fable REQUIRED QUIET) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) +endif() +find_package(Boost REQUIRED QUIET) +find_package(CLI11 REQUIRED QUIET) set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) +find_package(Threads REQUIRED QUIET) include(TargetLinting) include(GNUInstallDirs) @@ -22,22 +21,34 @@ string(TIMESTAMP CLOE_ENGINE_TIMESTAMP "%Y-%m-%d") set(CLOE_ENGINE_VERSION ${CLOE_PROJECT_VERSION}) set(PROJECT_GIT_REF "unknown") -# Library ------------------------------------------------------------ -add_library(${libstack} +# Library libstack --------------------------------------------------- +message(STATUS "Building cloe-stacklib library.") +add_library(cloe-stacklib STATIC + src/stack.hpp src/stack.cpp + src/plugin.hpp src/plugin.cpp + + # Built-in plugins: + src/plugins/nop_controller.cpp + src/plugins/nop_controller.hpp + src/plugins/nop_simulator.cpp + src/plugins/nop_simulator.hpp ) -set_target_properties(${libstack} PROPERTIES +add_library(cloe::stacklib ALIAS cloe-stacklib) +set_target_properties(cloe-stacklib PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON + OUTPUT_NAME stack ) -target_include_directories(${libstack} +target_include_directories(cloe-stacklib PRIVATE src ) -target_link_libraries(${libstack} +target_link_libraries(cloe-stacklib PUBLIC cloe::runtime + cloe::models fable::fable Boost::headers Threads::Threads @@ -46,91 +57,90 @@ target_link_libraries(${libstack} include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) - set(test-libstack test-${libstack}) - add_executable(${test-libstack} + message(STATUS "Building test-stacklib executable.") + add_executable(test-stacklib src/stack_test.cpp ) - set_target_properties(${test-libstack} PROPERTIES + set_target_properties(test-stacklib PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON ) - target_link_libraries(${test-libstack} + target_link_libraries(test-stacklib GTest::gtest GTest::gtest_main Boost::boost cloe::models - ${libstack} + cloe::stacklib ) - gtest_add_tests(TARGET ${test-libstack}) + gtest_add_tests(TARGET test-stacklib) endif() # Executable --------------------------------------------------------- -add_executable(${target} +add_executable(cloe-engine src/main.cpp src/main_stack.cpp src/coordinator.cpp - src/plugins/nop_controller.cpp - src/plugins/nop_simulator.cpp src/simulation.cpp src/simulation_context.cpp src/utility/command.cpp ) -set_target_properties(${target} PROPERTIES +set_target_properties(cloe-engine PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON - OUTPUT_NAME ${output} + OUTPUT_NAME cloe-engine ) -target_compile_definitions(${target} +target_compile_definitions(cloe-engine PRIVATE CLOE_ENGINE_VERSION="${CLOE_ENGINE_VERSION}" CLOE_ENGINE_TIMESTAMP="${CLOE_ENGINE_TIMESTAMP}" PROJECT_SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\" ) -set_target_linting(${target}) -target_include_directories(${target} +target_include_directories(cloe-engine PRIVATE src ) -target_link_libraries(${target} +target_link_libraries(cloe-engine PRIVATE CLI11::CLI11 cloe::models - ${libstack} + cloe::stacklib ) option(CLOE_ENGINE_WITH_SERVER "Enable integrated server component?" ON) if(CLOE_ENGINE_WITH_SERVER) message(STATUS "-> Enable server component") - find_package(cloe-oak REQUIRED) - target_sources(${target} + if(CLOE_FIND_PACKAGES) + find_package(cloe-oak REQUIRED QUIET) + endif() + target_sources(cloe-engine PRIVATE src/server.cpp ) - target_link_libraries(${target} + target_link_libraries(cloe-engine PRIVATE cloe::oak ) - target_compile_definitions(${target} + target_compile_definitions(cloe-engine PRIVATE CLOE_ENGINE_WITH_SERVER=1 ) else() message(STATUS "-> Disable server component") - target_sources(${target} + target_sources(cloe-engine PRIVATE src/server_mock.cpp ) - target_compile_definitions(${target} + target_compile_definitions(cloe-engine PRIVATE CLOE_ENGINE_WITH_SERVER=0 ) endif() # Installation ------------------------------------------------------- -install(TARGETS ${target} +install(TARGETS cloe-engine RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) diff --git a/engine/conanfile.py b/engine/conanfile.py index 5e9866f86..6593e1569 100644 --- a/engine/conanfile.py +++ b/engine/conanfile.py @@ -56,10 +56,10 @@ def requirements(self): self.requires(f"cloe-oak/{self.version}@cloe/develop", private=True) self.requires("boost/1.74.0") self.requires("fmt/9.1.0", override=True) - self.requires("nlohmann_json/3.11.2", override=True) + self.requires("nlohmann_json/3.11.3", override=True) def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) @@ -113,7 +113,8 @@ def package_info(self): self.cpp_info.system_libs.append("dl") if self.in_local_cache: bindir = os.path.join(self.package_folder, "bin") - else: - bindir = os.path.join(self.build_folder, str(self.settings.build_type), "bin") + else: # editable mode + bindir = os.path.join(self.build_folder) + self.output.info(f"Appending PATH environment variable: {bindir}") - self.env_info.PATH.append(bindir) + self.runenv_info.prepend_path("PATH", bindir) diff --git a/engine/tests/conanfile_with_server.py b/engine/tests/conanfile_with_server.py deleted file mode 100644 index b194ba952..000000000 --- a/engine/tests/conanfile_with_server.py +++ /dev/null @@ -1,32 +0,0 @@ -# mypy: ignore-errors -# pylint: skip-file - -from pathlib import Path - -from conan import ConanFile - - -class CloeTest(ConanFile): - python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" - python_requires_extend = "cloe-launch-profile.Base" - - @property - def cloe_launch_env(self): - return { - "CLOE_ENGINE_WITH_SERVER": "0", - "CLOE_LOG_LEVEL": "debug", - "CLOE_STRICT_MODE": "1", - "CLOE_WRITE_OUTPUT": "0", - "CLOE_ROOT": Path(self.recipe_folder) / "../..", - } - - def set_version(self): - self.version = self.project_version("../../VERSION") - - def requirements(self): - self.requires(f"cloe-engine/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-basic/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-mocks/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-noisy-sensor/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-speedometer/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-virtue/{self.version}@cloe/develop") diff --git a/engine/tests/conanfile_without_server.py b/engine/tests/conanfile_without_server.py deleted file mode 100644 index 0baebe875..000000000 --- a/engine/tests/conanfile_without_server.py +++ /dev/null @@ -1,35 +0,0 @@ -# mypy: ignore-errors -# pylint: skip-file - -from pathlib import Path - -from conan import ConanFile - - -class CloeTest(ConanFile): - python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" - python_requires_extend = "cloe-launch-profile.Base" - default_options = { - "cloe-engine:server": False, - } - - @property - def cloe_launch_env(self): - return { - "CLOE_ENGINE_WITH_SERVER": "0", - "CLOE_LOG_LEVEL": "debug", - "CLOE_STRICT_MODE": "1", - "CLOE_WRITE_OUTPUT": "0", - "CLOE_ROOT": Path(self.recipe_folder) / "../..", - } - - def set_version(self): - self.version = self.project_version("../../VERSION") - - def requirements(self): - self.requires(f"cloe-engine/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-basic/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-mocks/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-noisy-sensor/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-speedometer/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-virtue/{self.version}@cloe/develop") diff --git a/engine/tests/config_nop_infinite.json b/engine/tests/config_nop_infinite.json deleted file mode 100644 index e29064ef0..000000000 --- a/engine/tests/config_nop_infinite.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": "4", - "include": [ - "controller_virtue.json", - "controller_basic.json" - ], - "simulators": [ - { - "binding": "nop" - } - ], - "vehicles": [ - { - "name": "default", - "from": { - "simulator": "nop", - "index": 0 - }, - "components": { - "cloe::speedometer": { - "binding": "speedometer", - "name": "default_speed", - "from": "cloe::gndtruth_ego_sensor" - }, - "cloe::default_world_sensor": { - "binding": "noisy_object_sensor", - "name": "noisy_object_sensor", - "from": "cloe::default_world_sensor", - "args": { - "noise": [ - { - "target": "translation", - "distribution": { - "binding": "normal", - "mean": 0.0, - "std_deviation": 0.3 - } - } - ] - } - } - } - } - ] -} diff --git a/engine/tests/config_nop_smoketest.json b/engine/tests/config_nop_smoketest.json deleted file mode 100644 index 238708186..000000000 --- a/engine/tests/config_nop_smoketest.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "4", - "include": [ - "config_nop_infinite.json" - ], - "server": { - "listen": false, - "listen_port": 23456 - }, - "triggers": [ - {"event": "virtue/failure", "action": "fail"}, - { - "label": "Vehicle default should never move with the nop binding.", - "event": "default_speed/kmph=>0.0", "action": "fail" - }, - {"event": "start", "action": "log=info: Running nop/basic smoketest."}, - {"event": "start", "action": "realtime_factor=-1"}, - {"event": "time=60", "action": "succeed"} - ] -} diff --git a/fable/CMakeLists.txt b/fable/CMakeLists.txt index b7ee95e1e..e4969f619 100644 --- a/fable/CMakeLists.txt +++ b/fable/CMakeLists.txt @@ -1,7 +1,9 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(fable LANGUAGES CXX) +option(FABLE_ALLOW_COMMENTS "Allow comments when parsing JSON?" ON) + # NOTE: The variable FABLE_VERSION is used throughout this CMakeLists file # and is supplied from Conan or by hand on the command line. set(FABLE_VERSION "0.0.0-undefined" CACHE STRING "Fable version as MAJOR.MINOR.PATCH string") @@ -10,10 +12,11 @@ set(FABLE_VERSION_U32 0 CACHE STRING "Fable version as (MAJOR<<16)|(MINOR<<8)|PA include(GNUInstallDirs) # Library ------------------------------------------------------------ -find_package(fmt REQUIRED) -find_package(nlohmann_json REQUIRED) +find_package(fmt REQUIRED QUIET) +find_package(nlohmann_json REQUIRED QUIET) file(GLOB fable_PUBLIC_HEADERS "include/**/*.hpp") +message(STATUS "Building fable library [with comments=${FABLE_ALLOW_COMMENTS}].") add_library(fable # find src -type f -name "*.cpp" \! -name "*_test.cpp" src/fable/conf.cpp @@ -55,7 +58,6 @@ target_link_libraries(fable stdc++fs ) -option(FABLE_ALLOW_COMMENTS "Allow comments when parsing JSON?" ON) if(FABLE_ALLOW_COMMENTS) target_compile_definitions(fable PRIVATE PARSE_JSON_WITH_COMMENTS=true) else() @@ -63,14 +65,14 @@ else() endif() # Testing ------------------------------------------------------------ -set(CMAKE_CTEST_ARGUMENTS "--output-on-failure") include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) - find_package(Boost COMPONENTS headers filesystem REQUIRED) - find_package(sol2 REQUIRED) + find_package(GTest REQUIRED QUIET) + find_package(Boost COMPONENTS headers filesystem REQUIRED QUIET) + find_package(sol2 REQUIRED QUIET) include(GoogleTest) + message(STATUS "Building test-fable executable.") add_executable(test-fable # find src -type f -name "*_test.cpp" src/fable/version_test.cpp diff --git a/fable/conanfile.py b/fable/conanfile.py index 047b41c3a..503b19740 100644 --- a/fable/conanfile.py +++ b/fable/conanfile.py @@ -47,10 +47,10 @@ def set_version(self): def requirements(self): self.requires("fmt/9.1.0") - self.requires("nlohmann_json/3.11.2") + self.requires("nlohmann_json/3.11.3") def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") self.test_requires("boost/1.74.0") self.test_requires("sol2/3.3.0") diff --git a/fable/examples/contacts/CMakeLists.txt b/fable/examples/contacts/CMakeLists.txt index a3b1961df..eb04d7f1c 100644 --- a/fable/examples/contacts/CMakeLists.txt +++ b/fable/examples/contacts/CMakeLists.txt @@ -1,21 +1,20 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(fable_example_contacts LANGUAGES CXX) -find_package(CLI11 REQUIRED) -find_package(fable REQUIRED) -find_package(fmt REQUIRED) +find_package(CLI11 REQUIRED QUIET) +find_package(fable REQUIRED QUIET) +find_package(fmt REQUIRED QUIET) # Executable --------------------------------------------------------- -set(target contacts) -add_executable(${target} +add_executable(contacts src/main.cpp ) -set_target_properties(${target} PROPERTIES +set_target_properties(contacts PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON ) -target_link_libraries(${target} +target_link_libraries(contacts PRIVATE fable::fable fmt::fmt diff --git a/fable/examples/simple_config/CMakeLists.txt b/fable/examples/simple_config/CMakeLists.txt index 51d76b878..7917c1e9a 100644 --- a/fable/examples/simple_config/CMakeLists.txt +++ b/fable/examples/simple_config/CMakeLists.txt @@ -1,20 +1,19 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(fable_example_simple_config LANGUAGES CXX) -find_package(CLI11 REQUIRED) -find_package(fable REQUIRED) +find_package(CLI11 REQUIRED QUIET) +find_package(fable REQUIRED QUIET) # Executable --------------------------------------------------------- -set(target simple-config) -add_executable(${target} +add_executable(simple-config src/main.cpp ) -set_target_properties(${target} PROPERTIES +set_target_properties(simple-config PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON ) -target_link_libraries(${target} +target_link_libraries(simple-config PRIVATE fable::fable CLI11::CLI11 diff --git a/fable/examples/stress/CMakeLists.txt b/fable/examples/stress/CMakeLists.txt index 0233ff7db..bb462b50d 100644 --- a/fable/examples/stress/CMakeLists.txt +++ b/fable/examples/stress/CMakeLists.txt @@ -1,12 +1,12 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(fable_stress_test LANGUAGES CXX) set(LARGE_STRUCT_SIZE 1000 CACHE NUMBER "Number of members of Large struct") -find_package(CLI11 REQUIRED) -find_package(fable REQUIRED) -find_package(fmt REQUIRED) +find_package(CLI11 REQUIRED QUIET) +find_package(fable REQUIRED QUIET) +find_package(fmt REQUIRED QUIET) # Executable --------------------------------------------------------- add_custom_command( diff --git a/fable/test_v2_package/CMakeLists.txt b/fable/test_v2_package/CMakeLists.txt index a88553d3b..162cf5168 100644 --- a/fable/test_v2_package/CMakeLists.txt +++ b/fable/test_v2_package/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(fable_examples) diff --git a/models/CMakeLists.txt b/models/CMakeLists.txt index b3d436fce..881d7d09d 100644 --- a/models/CMakeLists.txt +++ b/models/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe-models LANGUAGES CXX) @@ -6,16 +6,16 @@ include(GNUInstallDirs) include(TargetLinting) # Module ------------------------------------------------------------- -set(target cloe-models) -set(alias cloe::models) - -find_package(cloe-runtime REQUIRED) -find_package(Eigen3 REQUIRED) -find_package(Boost COMPONENTS headers REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) +endif() +find_package(Eigen3 REQUIRED QUIET) +find_package(Boost COMPONENTS headers REQUIRED QUIET) -message(STATUS "-> Building ${output} library.") -file(GLOB ${target}_PUBLIC_HEADERS "include/**/*.hpp") -add_library(${target} +message(STATUS "Building cloe-models library.") +file(GLOB cloe-models_PUBLIC_HEADERS "include/**/*.hpp") +add_library(cloe-models # find src -type f -name "*.cpp" \! -name "*_test.cpp" src/cloe/component/lane_boundary.cpp src/cloe/component/utility/ego_sensor_canon.cpp @@ -23,21 +23,20 @@ add_library(${target} src/cloe/utility/actuation_state.cpp # For IDE integration - ${${target}_PUBLIC_HEADERS} + ${cloe-models_PUBLIC_HEADERS} ) -add_library(${alias} ALIAS ${target}) -set_target_properties(${target} PROPERTIES +add_library(cloe::models ALIAS cloe-models) +set_target_properties(cloe-models PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON VERSION ${CLOE_PROJECT_VERSION} ) -set_target_linting(${target}) -target_include_directories(${target} +target_include_directories(cloe-models PUBLIC "$" "$" ) -target_link_libraries(${target} +target_link_libraries(cloe-models PUBLIC cloe::runtime Boost::headers @@ -47,9 +46,10 @@ target_link_libraries(${target} # Testing ------------------------------------------------------------- include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) + message(STATUS "Building test-models executable.") add_executable(test-models # find src -type f -name "*_test.cpp" src/cloe/component/gearbox_actuator_test.cpp @@ -68,13 +68,13 @@ if(BUILD_TESTING) GTest::gtest_main Boost::boost cloe::runtime - ${target} + cloe-models ) gtest_add_tests(TARGET test-models) endif() # Installation ------------------------------------------------------- -install(TARGETS ${target} +install(TARGETS cloe-models LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE diff --git a/models/conanfile.py b/models/conanfile.py index e35e7cbf8..f6ab6aa4f 100644 --- a/models/conanfile.py +++ b/models/conanfile.py @@ -46,7 +46,7 @@ def requirements(self): self.requires("eigen/3.4.0") def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) diff --git a/oak/CMakeLists.txt b/oak/CMakeLists.txt index 4c17f1720..f64491cee 100644 --- a/oak/CMakeLists.txt +++ b/oak/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe-oak LANGUAGES CXX) @@ -6,37 +6,37 @@ include(GNUInstallDirs) include(TargetLinting) # Library ------------------------------------------------------------ -set(target cloe-oak) -set(alias cloe::oak) - -find_package(cloe-runtime REQUIRED) -find_package(oatpp REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) +endif() +find_package(oatpp REQUIRED QUIET) -file(GLOB ${target}_PUBLIC_HEADERS "include/**/*.hpp") -add_library(${target} +file(GLOB cloe-oak_PUBLIC_HEADERS "include/**/*.hpp") +message(STATUS "Building cloe-oak library.") +add_library(cloe-oak # find src -type f -name "*.cpp" \! -name "*_test.cpp" src/oak/registrar.cpp src/oak/server.cpp # For IDE integration - ${${target}_PUBLIC_HEADERS} + ${cloe-oak_PUBLIC_HEADERS} src/oak/request_stub.hpp src/oak/curl.hpp ) -add_library(${alias} ALIAS ${target}) -set_target_linting(${target}) -set_target_properties(${target} PROPERTIES +add_library(cloe::oak ALIAS cloe-oak) +set_target_properties(cloe-oak PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON ) -target_include_directories(${target} +target_include_directories(cloe-oak PRIVATE "$" PUBLIC "$" "$" ) -target_link_libraries(${target} +target_link_libraries(cloe-oak PUBLIC cloe::runtime oatpp::oatpp @@ -46,9 +46,10 @@ target_link_libraries(${target} # Testing ------------------------------------------------------------ include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) + message(STATUS "Building test-oak executable.") add_executable(test-oak # find src -type f -name "*_test.cpp" src/oak/route_muxer_test.cpp @@ -65,13 +66,13 @@ if(BUILD_TESTING) target_link_libraries(test-oak GTest::gtest GTest::gtest_main - ${target} + cloe-oak ) gtest_add_tests(TARGET test-oak) endif() # Installation ------------------------------------------------------- -install(TARGETS ${target} +install(TARGETS cloe-oak LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE diff --git a/oak/conanfile.py b/oak/conanfile.py index 2607abab2..abc79318a 100644 --- a/oak/conanfile.py +++ b/oak/conanfile.py @@ -45,7 +45,7 @@ def requirements(self): self.requires("oatpp/1.3.0") def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) diff --git a/optional/example_external/.gitignore b/optional/example_external/.gitignore new file mode 100644 index 000000000..567609b12 --- /dev/null +++ b/optional/example_external/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/optional/example_external/CMakeLists.txt b/optional/example_external/CMakeLists.txt new file mode 100644 index 000000000..cdf2a0f16 --- /dev/null +++ b/optional/example_external/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) + +project(cloe_plugin_example_external LANGUAGES CXX) + +find_package(cloe-runtime REQUIRED QUIET) +find_package(cloe-models REQUIRED QUIET) + +include(CloePluginSetup) +cloe_add_plugin( + TARGET controller_example_external + SOURCES + src/external_printer.cpp + LINK_LIBRARIES + cloe::runtime + cloe::models +) diff --git a/optional/example_external/Makefile b/optional/example_external/Makefile new file mode 100644 index 000000000..759272674 --- /dev/null +++ b/optional/example_external/Makefile @@ -0,0 +1 @@ +include ../../Makefile.package diff --git a/optional/example_external/conanfile.py b/optional/example_external/conanfile.py new file mode 100644 index 000000000..4d80ffc0f --- /dev/null +++ b/optional/example_external/conanfile.py @@ -0,0 +1,65 @@ +# mypy: ignore-errors +# pylint: skip-file + +from pathlib import Path + +from conan import ConanFile +from conan.tools import cmake, files, scm + +required_conan_version = ">=1.52.0" + + +class CloeControllerExampleExternal(ConanFile): + """ + This package is used for internal tests, and is not part of the + cloe package distribution. This is used for testing combining + external packages and cloe with Conan. + """ + + name = "cloe-plugin-example-external" + url = "https://github.com/eclipse/cloe" + description = "Cloe controller plugin mocks used for testing integration" + license = "Apache-2.0" + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeDeps", "CMakeToolchain" + no_copy_source = True + exports_sources = [ + "src/*", + "CMakeLists.txt", + ] + + def set_version(self): + version_file = Path(self.recipe_folder) / "../../VERSION" + if version_file.exists(): + self.version = files.load(self, version_file).strip() + else: + git = scm.Git(self, self.recipe_folder) + self.version = git.run("describe --dirty=-dirty")[1:] + + def requirements(self): + self.requires(f"cloe-runtime/{self.version}@cloe/develop") + self.requires(f"cloe-models/{self.version}@cloe/develop") + + def layout(self): + cmake.cmake_layout(self) + + def build(self): + cm = cmake.CMake(self) + if self.should_configure: + cm.configure() + if self.should_build: + cm.build() + + def package(self): + cm = cmake.CMake(self) + if self.should_install: + cm.install() + + def package_info(self): + self.cpp_info.set_property("cmake_find_mode", "both") + self.cpp_info.set_property("cmake_file_name", self.name) + self.cpp_info.set_property("pkg_config_name", self.name) + + if not self.in_local_cache: # editable mode + libdir = Path(self.build_folder) / "lib" + self.runenv_info.append_path("LD_LIBRARY_PATH", str(libdir)) diff --git a/optional/example_external/src/external_printer.cpp b/optional/example_external/src/external_printer.cpp new file mode 100644 index 000000000..54c550a83 --- /dev/null +++ b/optional/example_external/src/external_printer.cpp @@ -0,0 +1,76 @@ +/* + * Copyright 2024 Robert Bosch GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * \file external_printer.cpp + */ + +#include // for assert + +#include // for ObjectSensor +#include // for Controller, ControllerFactory, ... +#include // for CloeComponent +#include // for EXPORT_CLOE_PLUGIN +#include // for Sync +#include // for Vehicle + +namespace external { + +struct ExternalPrinterConf : public cloe::Confable { + CONFABLE_FRIENDS(ExternalPrinterConf) +}; + +class ExternalPrinter : public cloe::Controller { + public: + using Controller::Controller; + + void reset() override { + // Nothing to do here. + } + + void abort() override { + // Nothing to do here. + } + + cloe::Duration process(const cloe::Sync& sync) override { + assert(veh_ != nullptr); + auto log = this->logger(); + log->info("External Step {} @ {}", sync.step(), sync.time().count()); + if (veh_->has(cloe::CloeComponent::DEFAULT_WORLD_SENSOR)) { + auto sensor = veh_->get(cloe::CloeComponent::DEFAULT_WORLD_SENSOR); + auto& objs = sensor->sensed_objects(); + log->info(" {} Objects", objs.size()); + for (auto o : objs) { + log->info(" id={} pos=({:3f}, {:3f}, {:3f})", o->id, o->pose.translation()(0), + o->pose.translation()(1), o->pose.translation()(2)); + } + } + return sync.time(); + } +}; + +DEFINE_CONTROLLER_FACTORY(ExternalPrinterFactory, ExternalPrinterConf, "external_printer", + "print a lot of information") + +std::unique_ptr ExternalPrinterFactory::make(const cloe::Conf&) const { + return std::make_unique(this->name()); +} + +} // namespace external + +// Register factory as plugin entrypoint +EXPORT_CLOE_PLUGIN(external::ExternalPrinterFactory) diff --git a/optional/vtd/CMakeLists.txt b/optional/vtd/CMakeLists.txt index 9452257da..847911d79 100644 --- a/optional/vtd/CMakeLists.txt +++ b/optional/vtd/CMakeLists.txt @@ -1,13 +1,13 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_vtd LANGUAGES CXX) # Cloe Plugin -------------------------------------------------------- -find_package(vtd-api REQUIRED) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) -find_package(cloe-osi REQUIRED) -find_package(Boost REQUIRED) +find_package(vtd-api REQUIRED QUIET) +find_package(cloe-runtime REQUIRED QUIET) +find_package(cloe-models REQUIRED QUIET) +find_package(cloe-osi REQUIRED QUIET) +find_package(Boost REQUIRED QUIET) add_library(vtd-object-lib STATIC src/omni_sensor_component.cpp @@ -51,7 +51,7 @@ cloe_add_plugin( include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) add_executable(test-vtd-binding diff --git a/optional/vtd/conanfile.py b/optional/vtd/conanfile.py index 9763d6a0c..f955e93e0 100644 --- a/optional/vtd/conanfile.py +++ b/optional/vtd/conanfile.py @@ -50,14 +50,14 @@ def requirements(self): # Overrides, same as in the cloe conanfile.py: self.requires("protobuf/[>=3.9.1]", override=True) - self.requires("zlib/1.2.12", override=True) + self.requires("zlib/1.2.13", override=True) self.requires("fmt/9.1.0", override=True) self.requires("inja/3.4.0", override=True) - self.requires("nlohmann_json/3.11.2", override=True) + self.requires("nlohmann_json/3.11.3", override=True) self.requires("incbin/cci.20211107", override=True), def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def _compress_and_remove(self, dir): # reset() will remove the packages metadata diff --git a/optional/vtd/vendor/osi-sensor-1.0.0/CMakeLists.txt b/optional/vtd/vendor/osi-sensor-1.0.0/CMakeLists.txt index 4ae722682..d7a209ffe 100644 --- a/optional/vtd/vendor/osi-sensor-1.0.0/CMakeLists.txt +++ b/optional/vtd/vendor/osi-sensor-1.0.0/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(OSMPDummySensor LANGUAGES CXX) @@ -8,8 +8,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(VTD_ROOT "" CACHE STRING "Path to VTD root directory") # Dependencies -find_package(open_simulation_interface REQUIRED) -find_package(Protobuf CONFIG REQUIRED) +find_package(open_simulation_interface REQUIRED QUIET) +find_package(Protobuf CONFIG REQUIRED QUIET) find_library(VTD_OSI_LIBRARY NAME libopen_simulation_interface.so PATHS "${VTD_ROOT}/Data/Setups/Standard.OSI3/Bin/" NO_DEFAULT_PATH diff --git a/optional/vtd/vendor/protobuf-2.6.1/test_package/CMakeLists.txt b/optional/vtd/vendor/protobuf-2.6.1/test_package/CMakeLists.txt index c24d54471..bfee412c9 100644 --- a/optional/vtd/vendor/protobuf-2.6.1/test_package/CMakeLists.txt +++ b/optional/vtd/vendor/protobuf-2.6.1/test_package/CMakeLists.txt @@ -1,8 +1,8 @@ -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(test_package LANGUAGES CXX) -find_package(Protobuf CONFIG REQUIRED) +find_package(Protobuf CONFIG REQUIRED QUIET) add_executable(${PROJECT_NAME} test_package.cpp addressbook.proto) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11) diff --git a/optional/vtd/vendor/vtd-api-2.2.0/CMakeLists.txt b/optional/vtd/vendor/vtd-api-2.2.0/CMakeLists.txt index d10a2075a..fd4bdd4e7 100644 --- a/optional/vtd/vendor/vtd-api-2.2.0/CMakeLists.txt +++ b/optional/vtd/vendor/vtd-api-2.2.0/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(vtd_api LANGUAGES CXX VERSION 2.2.0) diff --git a/optional/vtd/vendor/vtd-api-2022.3/CMakeLists.txt b/optional/vtd/vendor/vtd-api-2022.3/CMakeLists.txt index 31c0fffb2..e43715364 100644 --- a/optional/vtd/vendor/vtd-api-2022.3/CMakeLists.txt +++ b/optional/vtd/vendor/vtd-api-2022.3/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(vtd_api LANGUAGES CXX VERSION 2022.3) diff --git a/osi/CMakeLists.txt b/osi/CMakeLists.txt index e5a2f5e96..3552594ac 100644 --- a/osi/CMakeLists.txt +++ b/osi/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe-osi LANGUAGES CXX) @@ -6,13 +6,17 @@ include(GNUInstallDirs) include(TargetLinting) # Module ------------------------------------------------------------- -find_package(cloe-models REQUIRED) -find_package(cloe-runtime REQUIRED) -find_package(Eigen3 REQUIRED) -find_package(Boost COMPONENTS headers REQUIRED) -find_package(open_simulation_interface REQUIRED) -message(STATUS "-> Building cloe-osi library.") +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-models REQUIRED QUIET) + find_package(cloe-runtime REQUIRED QUIET) +endif() +find_package(Eigen3 REQUIRED QUIET) +find_package(Boost COMPONENTS headers REQUIRED QUIET) +find_package(open_simulation_interface REQUIRED QUIET) + +message(STATUS "Building cloe-osi library.") file(GLOB cloe-osi_PUBLIC_HEADERS "include/**/*.hpp") add_library(cloe-osi # find src -type f -name "*.cpp" \! -name "*_test.cpp" @@ -48,9 +52,10 @@ target_link_libraries(cloe-osi # Testing ------------------------------------------------------------- include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) + message(STATUS "Building test-osi executable.") add_executable(test-osi # find src -type f -name "*_test.cpp" src/cloe/component/osi_sensor_test.cpp diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt new file mode 100644 index 000000000..b3987c5f4 --- /dev/null +++ b/plugins/CMakeLists.txt @@ -0,0 +1,50 @@ +# This CMakeLists.txt configures a super-build of all plugins. +# +# It is currently experimental. +# +# This supports two use-cases: +# +# 1. Creating a cloe-plugins-core package containing all plugins. +# 2. Creating a cloe package containing everything from this repo. +# +# Other use-cases are currently not supported. +# + +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) + +if(NOT DEFINED PROJECT_NAME) + project(cloe_plugins_core LANGUAGES CXX) + + option(CLOE_WITH_ESMINI "Build simulator_esmini plugin?" ON) + + # Speed up configuration by only finding Cloe packages once + set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") + if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) + set(CLOE_FIND_PACKAGES OFF FORCE) + endif() + + # Ensure output goes to one place so cloe-launch can find the plugins + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) +elseif(NOT ${PROJECT_NAME} STREQUAL "cloe") + message(FATAL_ERROR "Building super-project unequal to cloe not suppoorted.") +endif() + +# Ensure we can test from this level. +include(CTest) + +add_subdirectory(basic) +add_subdirectory(clothoid_fit) +add_subdirectory(frustum_culling) +add_subdirectory(gndtruth_extractor) +add_subdirectory(minimator) +add_subdirectory(mocks) +add_subdirectory(noisy_sensor) +add_subdirectory(speedometer) +add_subdirectory(virtue) + +if(CLOE_WITH_ESMINI) + add_subdirectory(esmini) +endif() diff --git a/plugins/Makefile b/plugins/Makefile new file mode 100644 index 000000000..87c6e44df --- /dev/null +++ b/plugins/Makefile @@ -0,0 +1 @@ +include ../Makefile.package diff --git a/plugins/basic/CMakeLists.txt b/plugins/basic/CMakeLists.txt index 35a6c490f..e5851ad8e 100644 --- a/plugins/basic/CMakeLists.txt +++ b/plugins/basic/CMakeLists.txt @@ -1,9 +1,12 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_basic LANGUAGES CXX) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) +endif() include(CloePluginSetup) cloe_add_plugin( @@ -20,7 +23,7 @@ cloe_add_plugin( include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) add_executable(test-basic-controller diff --git a/plugins/basic/conanfile.py b/plugins/basic/conanfile.py index 8bfc5b671..d4417de60 100644 --- a/plugins/basic/conanfile.py +++ b/plugins/basic/conanfile.py @@ -1,6 +1,7 @@ # mypy: ignore-errors # pylint: skip-file +import os from pathlib import Path from conan import ConanFile @@ -43,7 +44,7 @@ def requirements(self): self.requires(f"cloe-models/{self.version}@cloe/develop") def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) @@ -77,3 +78,7 @@ def package_info(self): self.cpp_info.set_property("cmake_find_mode", "both") self.cpp_info.set_property("cmake_file_name", self.name) self.cpp_info.set_property("pkg_config_name", self.name) + + if not self.in_local_cache: # editable mode + libdir = os.path.join(self.build_folder, "lib"); + self.runenv_info.append_path("LD_LIBRARY_PATH", libdir) diff --git a/plugins/clothoid_fit/CMakeLists.txt b/plugins/clothoid_fit/CMakeLists.txt index 64788208a..d4cb3f347 100644 --- a/plugins/clothoid_fit/CMakeLists.txt +++ b/plugins/clothoid_fit/CMakeLists.txt @@ -1,10 +1,13 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_clothoid_fit LANGUAGES CXX) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) -find_package(Eigen3 REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) +endif() +find_package(Eigen3 REQUIRED QUIET) add_library(g1-fitting-lib STATIC src/g1_fitting.cpp @@ -31,7 +34,7 @@ cloe_add_plugin( include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) add_executable(test-clothoid-fit diff --git a/plugins/clothoid_fit/conanfile.py b/plugins/clothoid_fit/conanfile.py index 853b566fd..4ad1f3892 100644 --- a/plugins/clothoid_fit/conanfile.py +++ b/plugins/clothoid_fit/conanfile.py @@ -35,7 +35,7 @@ def requirements(self): self.requires("eigen/3.4.0") def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) diff --git a/plugins/conanfile.py b/plugins/conanfile.py new file mode 100644 index 000000000..bf301e21a --- /dev/null +++ b/plugins/conanfile.py @@ -0,0 +1,88 @@ +# mypy: ignore-errors +# pylint: skip-file + +import os +from pathlib import Path + +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration +from conan.tools import cmake, files, scm, env + +required_conan_version = ">=1.52.0" + + +class CloeControllerBasic(ConanFile): + name = "cloe-plugins-core" + url = "https://github.com/eclipse/cloe" + description = "Cloe core plugins" + license = "Apache-2.0" + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeDeps", "VirtualRunEnv" + no_copy_source = True + provides = [ + "cloe-plugin-basic", + "cloe-plugin-gndtruth-extractor", + "cloe-plugin-minimator", + "cloe-plugin-mocks", + "cloe-plugin-noisy-sensor", + "cloe-plugin-speedometer", + "cloe-plugin-virtue", + ] + exports_sources = [ + "*/src/*", + "*/include/*", + "*/ui/*", + "*/CMakeLists.txt", + ] + + def set_version(self): + version_file = Path(self.recipe_folder) / "../VERSION" + if version_file.exists(): + self.version = files.load(self, version_file).strip() + else: + git = scm.Git(self, self.recipe_folder) + self.version = git.run("describe --dirty=-dirty")[1:] + + def requirements(self): + self.requires(f"cloe-runtime/{self.version}@cloe/develop") + self.requires(f"cloe-models/{self.version}@cloe/develop") + + def build_requirements(self): + self.test_requires("gtest/1.14.0") + + def layout(self): + cmake.cmake_layout(self) + + def generate(self): + tc = cmake.CMakeToolchain(self) + tc.cache_variables["CMAKE_EXPORT_COMPILE_COMMANDS"] = True + tc.cache_variables["CLOE_PROJECT_VERSION"] = self.version + tc.cache_variables["TargetLintingExtended"] = True + tc.generate() + + def build(self): + cm = cmake.CMake(self) + if self.should_configure: + cm.configure() + if self.should_build: + cm.build() + if self.should_test: + cm.test() + + def package(self): + cm = cmake.CMake(self) + if self.should_install: + cm.install() + + def package_id(self): + self.info.requires["boost"].full_package_mode() + del self.info.options.pedantic + + def package_info(self): + self.cpp_info.set_property("cmake_find_mode", "both") + self.cpp_info.set_property("cmake_file_name", self.name) + self.cpp_info.set_property("pkg_config_name", self.name) + + if not self.in_local_cache: + libdir = os.path.join(self.build_folder, "lib"); + self.runenv_info.append_path("LD_LIBRARY_PATH", libdir) diff --git a/plugins/esmini/CMakeLists.txt b/plugins/esmini/CMakeLists.txt index 53edeb3df..3730f1872 100644 --- a/plugins/esmini/CMakeLists.txt +++ b/plugins/esmini/CMakeLists.txt @@ -1,11 +1,14 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_esmini LANGUAGES CXX) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) -find_package(cloe-osi REQUIRED) -find_package(esmini REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) + find_package(cloe-osi REQUIRED QUIET) +endif() +find_package(esmini REQUIRED QUIET) include(CloePluginSetup) cloe_add_plugin( @@ -24,7 +27,7 @@ cloe_add_plugin( include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) add_executable(test-esmini diff --git a/plugins/esmini/conanfile.py b/plugins/esmini/conanfile.py index 487a57bf0..91167f627 100644 --- a/plugins/esmini/conanfile.py +++ b/plugins/esmini/conanfile.py @@ -36,7 +36,7 @@ def requirements(self): self.requires("zlib/1.2.13", override=True) # conflict between boost & protobuf def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) diff --git a/plugins/esmini/tests/conanfile_esmini.py b/plugins/esmini/tests/conanfile_esmini.py deleted file mode 100644 index f024b2934..000000000 --- a/plugins/esmini/tests/conanfile_esmini.py +++ /dev/null @@ -1,39 +0,0 @@ -# mypy: ignore-errors -# pylint: skip-file - -from pathlib import Path -from conan import ConanFile - - -class CloeTest(ConanFile): - python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" - python_requires_extend = "cloe-launch-profile.Base" - - default_options = { - "cloe-engine:server": True, - } - - @property - def cloe_launch_env(self): - return { - "CLOE_LOG_LEVEL": "debug", - "CLOE_STRICT_MODE": "1", - "CLOE_WRITE_OUTPUT": "0", - "CLOE_ROOT": Path(self.recipe_folder) / "../../..", - } - - def set_version(self): - self.version = self.project_version("../../../VERSION") - - def requirements(self): - self.requires(f"cloe-engine/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-basic/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-noisy-sensor/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-speedometer/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-gndtruth-extractor/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-virtue/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-esmini/{self.version}@cloe/develop") - self.requires("esmini-data/2.37.4@cloe/stable") - - # Overrides: - self.requires("zlib/1.2.13", override=True) diff --git a/plugins/esmini/tests/controller_virtue.json b/plugins/esmini/tests/controller_virtue.json deleted file mode 100644 index 15453a5fb..000000000 --- a/plugins/esmini/tests/controller_virtue.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "version": "4", - - "controllers": [ - { - "binding": "virtue", - "vehicle": "default" - } - ] -} diff --git a/plugins/frustum_culling/CMakeLists.txt b/plugins/frustum_culling/CMakeLists.txt index da8e22870..4a2c1e2eb 100644 --- a/plugins/frustum_culling/CMakeLists.txt +++ b/plugins/frustum_culling/CMakeLists.txt @@ -1,11 +1,11 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_frustum_culling LANGUAGES CXX) set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") if(CLOE_FIND_PACKAGES) - find_package(cloe-runtime REQUIRED) - find_package(cloe-models REQUIRED) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) endif() include(CloePluginSetup) @@ -29,7 +29,7 @@ cloe_add_plugin( set(CMAKE_CTEST_ARGUMENTS "--output-on-failure") include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) add_executable(test-frustum-culling diff --git a/plugins/frustum_culling/conanfile.py b/plugins/frustum_culling/conanfile.py index d70987b5d..7bacad4ef 100644 --- a/plugins/frustum_culling/conanfile.py +++ b/plugins/frustum_culling/conanfile.py @@ -42,10 +42,10 @@ def requirements(self): self.requires(f"cloe-runtime/{self.version}@cloe/develop") self.requires(f"cloe-models/{self.version}@cloe/develop") self.requires("fmt/9.1.0") - self.requires("nlohmann_json/3.11.2", override=True) + self.requires("nlohmann_json/3.11.3", override=True) def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) diff --git a/plugins/gndtruth_extractor/CMakeLists.txt b/plugins/gndtruth_extractor/CMakeLists.txt index ba56fac47..099dabd49 100644 --- a/plugins/gndtruth_extractor/CMakeLists.txt +++ b/plugins/gndtruth_extractor/CMakeLists.txt @@ -1,9 +1,12 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_gndtruth_extractor LANGUAGES CXX) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) +endif() include(CloePluginSetup) cloe_add_plugin( @@ -18,7 +21,7 @@ cloe_add_plugin( include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) add_executable(test-gndtruth-extractor diff --git a/plugins/gndtruth_extractor/conanfile.py b/plugins/gndtruth_extractor/conanfile.py index 96ff71041..d3b1afcac 100644 --- a/plugins/gndtruth_extractor/conanfile.py +++ b/plugins/gndtruth_extractor/conanfile.py @@ -1,6 +1,7 @@ # mypy: ignore-errors # pylint: skip-file +import os from pathlib import Path from conan import ConanFile @@ -42,7 +43,7 @@ def requirements(self): self.requires(f"cloe-models/{self.version}@cloe/develop") def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) @@ -76,3 +77,7 @@ def package_info(self): self.cpp_info.set_property("cmake_find_mode", f"both") self.cpp_info.set_property("cmake_file_name", self.name) self.cpp_info.set_property("pkg_config_name", self.name) + + if not self.in_local_cache: # editable mode + libdir = os.path.join(self.build_folder, "lib"); + self.runenv_info.append_path("LD_LIBRARY_PATH", libdir) diff --git a/plugins/gndtruth_extractor/tests/conanfile_default.py b/plugins/gndtruth_extractor/tests/conanfile_default.py deleted file mode 100644 index 456b73752..000000000 --- a/plugins/gndtruth_extractor/tests/conanfile_default.py +++ /dev/null @@ -1,32 +0,0 @@ -# mypy: ignore-errors -# pylint: skip-file - -from pathlib import Path -from conan import ConanFile - - -class CloeTest(ConanFile): - python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" - python_requires_extend = "cloe-launch-profile.Base" - - default_options = { - "cloe-engine:server": False, - } - - @property - def cloe_launch_env(self): - return { - "CLOE_LOG_LEVEL": "debug", - "CLOE_STRICT_MODE": "1", - "CLOE_WRITE_OUTPUT": "0", - "CLOE_ROOT": Path(self.recipe_folder) / "../../..", - } - - def set_version(self): - self.version = self.project_version("../../../VERSION") - - def requirements(self): - self.requires(f"cloe-engine/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-basic/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-minimator/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-gndtruth-extractor/{self.version}@cloe/develop") diff --git a/plugins/minimator/CMakeLists.txt b/plugins/minimator/CMakeLists.txt index 4986e1855..3a084266d 100644 --- a/plugins/minimator/CMakeLists.txt +++ b/plugins/minimator/CMakeLists.txt @@ -1,9 +1,12 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_minimator LANGUAGES CXX) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) +endif() include(CloePluginSetup) cloe_add_plugin( @@ -20,7 +23,7 @@ cloe_add_plugin( include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) set(test-minimator test-${PROJECT_NAME}) diff --git a/plugins/minimator/conanfile.py b/plugins/minimator/conanfile.py index b0a59af0f..48b99e813 100644 --- a/plugins/minimator/conanfile.py +++ b/plugins/minimator/conanfile.py @@ -1,6 +1,7 @@ # mypy: ignore-errors # pylint: skip-file +import os from pathlib import Path from conan import ConanFile @@ -43,7 +44,7 @@ def requirements(self): self.requires(f"cloe-models/{self.version}@cloe/develop") def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) @@ -77,3 +78,7 @@ def package_info(self): self.cpp_info.set_property("cmake_find_mode", "both") self.cpp_info.set_property("cmake_file_name", self.name) self.cpp_info.set_property("pkg_config_name", self.name) + + if not self.in_local_cache: # editable mode + libdir = os.path.join(self.build_folder, "lib"); + self.runenv_info.append_path("LD_LIBRARY_PATH", libdir) diff --git a/plugins/minimator/tests/conanfile_default.py b/plugins/minimator/tests/conanfile_default.py deleted file mode 100644 index 175270414..000000000 --- a/plugins/minimator/tests/conanfile_default.py +++ /dev/null @@ -1,36 +0,0 @@ -# mypy: ignore-errors -# pylint: skip-file - -from pathlib import Path - -from conan import ConanFile - - -class CloeTest(ConanFile): - python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" - python_requires_extend = "cloe-launch-profile.Base" - - default_options = { - "cloe-engine:server": True, - } - - @property - def cloe_launch_env(self): - return { - "CLOE_LOG_LEVEL": "debug", - "CLOE_STRICT_MODE": "1", - "CLOE_WRITE_OUTPUT": "0", - "CLOE_ROOT": Path(self.recipe_folder) / "../../..", - } - - def set_version(self): - self.version = self.project_version("../../../VERSION") - - def requirements(self): - self.requires(f"cloe-engine/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-basic/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-clothoid-fit/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-minimator/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-noisy-sensor/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-speedometer/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-virtue/{self.version}@cloe/develop") diff --git a/plugins/mocks/CMakeLists.txt b/plugins/mocks/CMakeLists.txt index b21f67bb0..afd20059a 100644 --- a/plugins/mocks/CMakeLists.txt +++ b/plugins/mocks/CMakeLists.txt @@ -1,9 +1,12 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_mocks LANGUAGES CXX) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) +endif() include(CloePluginSetup) cloe_add_plugin( diff --git a/plugins/mocks/conanfile.py b/plugins/mocks/conanfile.py index 27b2ffebb..39667172e 100644 --- a/plugins/mocks/conanfile.py +++ b/plugins/mocks/conanfile.py @@ -1,6 +1,7 @@ # mypy: ignore-errors # pylint: skip-file +import os from pathlib import Path from conan import ConanFile @@ -71,3 +72,7 @@ def package_info(self): self.cpp_info.set_property("cmake_find_mode", "both") self.cpp_info.set_property("cmake_file_name", self.name) self.cpp_info.set_property("pkg_config_name", self.name) + + if not self.in_local_cache: # editable mode + libdir = os.path.join(self.build_folder, "lib"); + self.runenv_info.append_path("LD_LIBRARY_PATH", libdir) diff --git a/plugins/noisy_sensor/CMakeLists.txt b/plugins/noisy_sensor/CMakeLists.txt index 0245e916d..d9e5c48d0 100644 --- a/plugins/noisy_sensor/CMakeLists.txt +++ b/plugins/noisy_sensor/CMakeLists.txt @@ -1,9 +1,12 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_noisy_sensors LANGUAGES CXX) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) +endif() include(CloePluginSetup) cloe_add_plugin( @@ -25,7 +28,7 @@ cloe_add_plugin( include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) add_executable(test-noisy-sensor diff --git a/plugins/noisy_sensor/conanfile.py b/plugins/noisy_sensor/conanfile.py index 1ec756da3..ff9a5fbb4 100644 --- a/plugins/noisy_sensor/conanfile.py +++ b/plugins/noisy_sensor/conanfile.py @@ -1,6 +1,7 @@ # mypy: ignore-errors # pylint: skip-file +import os from pathlib import Path from conan import ConanFile @@ -42,7 +43,7 @@ def requirements(self): self.requires(f"cloe-models/{self.version}@cloe/develop") def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) @@ -76,3 +77,7 @@ def package_info(self): self.cpp_info.set_property("cmake_find_mode", "both") self.cpp_info.set_property("cmake_file_name", self.name) self.cpp_info.set_property("pkg_config_name", self.name) + + if not self.in_local_cache: # editable mode + libdir = os.path.join(self.build_folder, "lib"); + self.runenv_info.append_path("LD_LIBRARY_PATH", libdir) diff --git a/plugins/speedometer/CMakeLists.txt b/plugins/speedometer/CMakeLists.txt index d6465a593..1004d6fd4 100644 --- a/plugins/speedometer/CMakeLists.txt +++ b/plugins/speedometer/CMakeLists.txt @@ -1,9 +1,12 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_speedometer LANGUAGES CXX) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) +endif() include(CloePluginSetup) cloe_add_plugin( diff --git a/plugins/speedometer/conanfile.py b/plugins/speedometer/conanfile.py index 9ab5e1eda..e9e0ce661 100644 --- a/plugins/speedometer/conanfile.py +++ b/plugins/speedometer/conanfile.py @@ -1,6 +1,7 @@ # mypy: ignore-errors # pylint: skip-file +import os from pathlib import Path from conan import ConanFile @@ -71,3 +72,7 @@ def package_info(self): self.cpp_info.set_property("cmake_find_mode", "both") self.cpp_info.set_property("cmake_file_name", self.name) self.cpp_info.set_property("pkg_config_name", self.name) + + if not self.in_local_cache: # editable mode + libdir = os.path.join(self.build_folder, "lib"); + self.runenv_info.append_path("LD_LIBRARY_PATH", libdir) diff --git a/plugins/virtue/CMakeLists.txt b/plugins/virtue/CMakeLists.txt index 5cecbc970..7b92fc14e 100644 --- a/plugins/virtue/CMakeLists.txt +++ b/plugins/virtue/CMakeLists.txt @@ -1,9 +1,12 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe_plugin_virtue LANGUAGES CXX) -find_package(cloe-runtime REQUIRED) -find_package(cloe-models REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(cloe-runtime REQUIRED QUIET) + find_package(cloe-models REQUIRED QUIET) +endif() include(CloePluginSetup) cloe_add_plugin( diff --git a/plugins/virtue/conanfile.py b/plugins/virtue/conanfile.py index 5066a8cb4..3caf9d691 100644 --- a/plugins/virtue/conanfile.py +++ b/plugins/virtue/conanfile.py @@ -1,6 +1,7 @@ # mypy: ignore-errors # pylint: skip-file +import os from pathlib import Path from conan import ConanFile @@ -71,3 +72,7 @@ def package_info(self): self.cpp_info.set_property("cmake_find_mode", "both") self.cpp_info.set_property("cmake_file_name", self.name) self.cpp_info.set_property("pkg_config_name", self.name) + + if not self.in_local_cache: # editable mode + libdir = os.path.join(self.build_folder, "lib"); + self.runenv_info.append_path("LD_LIBRARY_PATH", libdir) diff --git a/plugins/virtue/tests/conanfile_default.py b/plugins/virtue/tests/conanfile_default.py deleted file mode 100644 index 175270414..000000000 --- a/plugins/virtue/tests/conanfile_default.py +++ /dev/null @@ -1,36 +0,0 @@ -# mypy: ignore-errors -# pylint: skip-file - -from pathlib import Path - -from conan import ConanFile - - -class CloeTest(ConanFile): - python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" - python_requires_extend = "cloe-launch-profile.Base" - - default_options = { - "cloe-engine:server": True, - } - - @property - def cloe_launch_env(self): - return { - "CLOE_LOG_LEVEL": "debug", - "CLOE_STRICT_MODE": "1", - "CLOE_WRITE_OUTPUT": "0", - "CLOE_ROOT": Path(self.recipe_folder) / "../../..", - } - - def set_version(self): - self.version = self.project_version("../../../VERSION") - - def requirements(self): - self.requires(f"cloe-engine/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-basic/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-clothoid-fit/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-minimator/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-noisy-sensor/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-speedometer/{self.version}@cloe/develop") - self.requires(f"cloe-plugin-virtue/{self.version}@cloe/develop") diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index e44ba61a9..d49101630 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(cloe-runtime LANGUAGES CXX) @@ -8,23 +8,23 @@ set(CLOE_VERSION "0.0.0-undefined" CACHE STRING "Cloe version as MAJOR.MINOR.PAT set(CLOE_VERSION_U32 0 CACHE STRING "Cloe version as (MAJOR<<16)|(MINOR<<8)|PATCH integer") include(GNUInstallDirs) -include(cmake/TargetLinting.cmake) # Library ------------------------------------------------------------- -set(target cloe-runtime) -set(alias cloe::runtime) - -find_package(fable REQUIRED) -find_package(Boost COMPONENTS headers filesystem iostreams system REQUIRED) -find_package(spdlog REQUIRED) -find_package(inja REQUIRED) +set(CLOE_FIND_PACKAGES ON CACHE BOOL "Call find_package() for cloe packages") +if(CLOE_FIND_PACKAGES) + find_package(fable REQUIRED QUIET) +endif() +find_package(Boost COMPONENTS headers filesystem iostreams system REQUIRED QUIET) +find_package(spdlog REQUIRED QUIET) +find_package(inja REQUIRED QUIET) if(NOT TARGET pantor::inja) add_library(pantor::inja ALIAS inja::inja) endif() -find_package(incbin REQUIRED) +find_package(incbin REQUIRED QUIET) -file(GLOB ${target}_PUBLIC_HEADERS "include/**/*.hpp") -add_library(${target} SHARED +file(GLOB cloe-runtime_PUBLIC_HEADERS "include/**/*.hpp") +message(STATUS "Building cloe-runtime library.") +add_library(cloe-runtime SHARED # find src -type f -name "*.cpp" \! -name "*_test.cpp" src/cloe/core/error.cpp src/cloe/core/duration.cpp @@ -47,23 +47,22 @@ add_library(${target} SHARED src/cloe/utility/xdg.cpp # For IDE integration - ${${target}_PUBLIC_HEADERS} + ${cloe-runtime_PUBLIC_HEADERS} ) -add_library(${alias} ALIAS ${target}) -set_target_properties(${target} PROPERTIES +add_library(cloe::runtime ALIAS cloe-runtime) +set_target_properties(cloe-runtime PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON VERSION ${CLOE_VERSION} ) -set_target_linting(${target}) configure_file(src/cloe/version.hpp.in include/cloe/version.hpp @ONLY) -target_include_directories(${target} +target_include_directories(cloe-runtime PUBLIC "$" "$" "$" ) -target_link_libraries(${target} +target_link_libraries(cloe-runtime PUBLIC Boost::headers Boost::filesystem @@ -75,7 +74,7 @@ target_link_libraries(${target} pantor::inja incbin::incbin ) -target_compile_definitions(${target} +target_compile_definitions(cloe-runtime PRIVATE PROJECT_SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\" PUBLIC @@ -85,9 +84,10 @@ target_compile_definitions(${target} # Testing ------------------------------------------------------------- include(CTest) if(BUILD_TESTING) - find_package(GTest REQUIRED) + find_package(GTest REQUIRED QUIET) include(GoogleTest) + message(STATUS "Building test-cloe executable.") add_executable(test-cloe # find src -type f -name "*_test.cpp" src/cloe/version_test.cpp @@ -103,13 +103,13 @@ if(BUILD_TESTING) GTest::gtest GTest::gtest_main Boost::boost - ${target} + cloe-runtime ) gtest_add_tests(TARGET test-cloe) endif() # Installation -------------------------------------------------------- -install(TARGETS ${target} +install(TARGETS cloe-runtime LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE diff --git a/runtime/cmake/CloePluginSetup.cmake b/runtime/cmake/CloePluginSetup.cmake index 7d8f6c4a1..8ad139a41 100644 --- a/runtime/cmake/CloePluginSetup.cmake +++ b/runtime/cmake/CloePluginSetup.cmake @@ -6,7 +6,7 @@ include(TargetLinting) function(cloe_add_plugin) set(options - NO_LINTING + LINT ) set(one_value_args TARGET # [required] @@ -44,11 +44,11 @@ function(cloe_add_plugin) message(SEND_ERROR "cloe_add_plugin requires property SOURCES to be set") endif() if(NOT DEFINED _ARG_OUTPUT_DIRECTORY) - set(_ARG_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/cloe) + set(_ARG_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/cloe) endif() # Add the cloe plugin target: - message(STATUS "-> Building ${_ARG_OUTPUT_NAME} plugin.") + message(STATUS "Building ${_ARG_OUTPUT_NAME} plugin.") add_library(${target} MODULE ${_ARG_SOURCES} ) @@ -71,7 +71,7 @@ function(cloe_add_plugin) OUTPUT_NAME ${_ARG_OUTPUT_NAME} PREFIX "" ) - if(NOT ${_ARG_NO_LINTING}) + if(${_ARG_LINT}) set_target_linting(${target}) endif() target_compile_options(${target} diff --git a/runtime/conanfile.py b/runtime/conanfile.py index 4021f5fdf..9cde7269f 100644 --- a/runtime/conanfile.py +++ b/runtime/conanfile.py @@ -51,7 +51,7 @@ def requirements(self): self.requires("incbin/cci.20211107") def build_requirements(self): - self.test_requires("gtest/1.13.0") + self.test_requires("gtest/1.14.0") def layout(self): cmake.cmake_layout(self) diff --git a/tests/conanfile_default.py b/tests/conanfile_default.py deleted file mode 100644 index f02947e98..000000000 --- a/tests/conanfile_default.py +++ /dev/null @@ -1,37 +0,0 @@ -# mypy: ignore-errors -# pylint: skip-file - -from pathlib import Path - -from conan import ConanFile - - -class CloeTest(ConanFile): - python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" - python_requires_extend = "cloe-launch-profile.Base" - - default_options = { - "cloe:with_vtd": False, - "cloe-engine:server": True, - } - - @property - def cloe_launch_env(self): - return { - "CLOE_LOG_LEVEL": "debug", - "CLOE_STRICT_MODE": "1", - "CLOE_WRITE_OUTPUT": "0", - "CLOE_ROOT": Path(self.recipe_folder) / "..", - } - - def set_version(self): - self.version = self.project_version("../VERSION") - - def requirements(self): - self.requires(f"cloe/{self.version}@cloe/develop") - if self.options["cloe"].with_vtd: - # These dependencies aren't pulled in by the "cloe" package, - # because they are not required to build the package. - # We need them to run the tests though. - self.requires("osi-sensor/1.0.0-vtd2.2@cloe/stable") - self.requires("vtd/2.2.0@cloe-restricted/stable") diff --git a/tests/conanfile_deployment.py b/tests/conanfile_deployment.py new file mode 100644 index 000000000..22e91d3ae --- /dev/null +++ b/tests/conanfile_deployment.py @@ -0,0 +1,90 @@ +# mypy: ignore-errors +# pylint: skip-file + +from pathlib import Path + +from conan import ConanFile +from conan.tools import files, scm + +required_conan_version = ">=1.52.0" + + +class CloeStandardDeployment(ConanFile): + python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" + python_requires_extend = "cloe-launch-profile.Base" + + name = "cloe-deployment" + license = "Apache-2.0" + url = "https://github.com/eclipse/cloe" + description = "Closed-loop automated driving simulation environment" + topics = ["simulation"] + settings = "os", "compiler", "build_type", "arch" + options = { + "with_esmini": [True, False], + "with_vtd": [True, False], + } + default_options = { + "with_esmini": True, + "with_vtd": False, + + "fable:allow_comments": True, + "cloe-engine:server": True, + } + + @property + def cloe_launch_env(self): + return { + "CLOE_ENGINE_WITH_SERVER": "1", + "CLOE_LOG_LEVEL": "debug", + "CLOE_STRICT_MODE": "1", + "CLOE_WRITE_OUTPUT": "0", + "CLOE_ROOT": Path(self.recipe_folder) / "..", + } + + def set_version(self): + version_file = Path(self.recipe_folder) / "../VERSION" + if version_file.exists(): + self.version = files.load(self, version_file).strip() + else: + git = scm.Git(self, self.recipe_folder) + self.version = git.run("describe --dirty=-dirty")[1:] + + def requirements(self): + def cloe_requires(dep): + self.requires(f"{dep}/{self.version}@cloe/develop") + + cloe_requires("cloe-runtime") + cloe_requires("cloe-models") + cloe_requires("cloe-osi") + cloe_requires("cloe-plugin-basic") + cloe_requires("cloe-plugin-clothoid-fit") + cloe_requires("cloe-plugin-frustum-culling") + cloe_requires("cloe-plugin-gndtruth-extractor") + cloe_requires("cloe-plugin-minimator") + cloe_requires("cloe-plugin-mocks") + cloe_requires("cloe-plugin-noisy-sensor") + cloe_requires("cloe-plugin-speedometer") + cloe_requires("cloe-plugin-virtue") + + if self.options.with_esmini: + cloe_requires("cloe-plugin-esmini") + + if self.options.with_vtd: + cloe_requires("cloe-plugin-vtd") + + # Overrides: + self.requires("fmt/9.1.0", override=True) + self.requires("inja/3.4.0", override=True) + self.requires("nlohmann_json/3.11.3", override=True) + self.requires("incbin/cci.20211107", override=True) + self.requires("boost/1.74.0", override=True) + self.requires("zlib/1.2.13", override=True) + self.requires("protobuf/3.21.12", override=True) + + # Runtime requirements: + cloe_requires("cloe-engine") + if self.options.with_esmini: + self.requires("esmini-data/2.37.4@cloe/stable") + if self.options.with_vtd: + self.requires("osi-sensor/1.0.0-vtd2.2@cloe/stable") + self.requires("vtd/2.2.0@cloe-restricted/stable") diff --git a/tests/conanfile_superbuild.py b/tests/conanfile_superbuild.py new file mode 100644 index 000000000..4410296aa --- /dev/null +++ b/tests/conanfile_superbuild.py @@ -0,0 +1,59 @@ +# mypy: ignore-errors +# pylint: skip-file + +from pathlib import Path + +from conan import ConanFile +from conan.tools import files, scm + +required_conan_version = ">=1.52.0" + + +class CloeSuperbuildTest(ConanFile): + python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" + python_requires_extend = "cloe-launch-profile.Base" + + name = "cloe-superbuild-test" + license = "Apache-2.0" + url = "https://github.com/eclipse/cloe" + description = "Closed-loop automated driving simulation environment" + topics = ["simulation"] + settings = "os", "compiler", "build_type", "arch" + options = { + "with_esmini": [True, False], + "with_vtd": [True, False], + } + default_options = { + "with_esmini": True, + "with_vtd": False, + + "cloe:fable_allow_comments": True, + "cloe:engine_server": True, + } + + @property + def cloe_launch_env(self): + return { + "CLOE_ENGINE_WITH_SERVER": "1" if self.options["cloe"].engine_server else "0", + "CLOE_LOG_LEVEL": "debug", + "CLOE_STRICT_MODE": "1", + "CLOE_WRITE_OUTPUT": "0", + "CLOE_ROOT": Path(self.recipe_folder) / "..", + } + + def configure(self): + self.options["cloe"].with_esmini = self.options.with_esmini + self.options["cloe"].with_vtd = self.options.with_vtd + + def set_version(self): + self.version = self.project_version("../VERSION") + + def requirements(self): + self.requires(f"cloe/{self.version}@cloe/develop") + + # Runtime requirements: + if self.options.with_esmini: + self.requires("esmini-data/2.37.4@cloe/stable") + if self.options.with_vtd: + self.requires("osi-sensor/1.0.0-vtd2.2@cloe/stable") + self.requires("vtd/2.2.0@cloe-restricted/stable") diff --git a/plugins/esmini/tests/config_esmini_aeb.json b/tests/config_esmini_aeb.json similarity index 100% rename from plugins/esmini/tests/config_esmini_aeb.json rename to tests/config_esmini_aeb.json diff --git a/plugins/esmini/tests/config_esmini_closed_loop.json b/tests/config_esmini_closed_loop.json similarity index 97% rename from plugins/esmini/tests/config_esmini_closed_loop.json rename to tests/config_esmini_closed_loop.json index 71452c373..b819f788e 100644 --- a/plugins/esmini/tests/config_esmini_closed_loop.json +++ b/tests/config_esmini_closed_loop.json @@ -27,7 +27,7 @@ { "label": "Ego vehicle should reach stand-still.", "event": "default_speed/kmph=<0.2", "action": "succeed" - } + } ] } } diff --git a/plugins/esmini/tests/config_esmini_cut_in.json b/tests/config_esmini_cut_in.json similarity index 100% rename from plugins/esmini/tests/config_esmini_cut_in.json rename to tests/config_esmini_cut_in.json diff --git a/plugins/esmini/tests/config_esmini_open_loop.json b/tests/config_esmini_open_loop.json similarity index 100% rename from plugins/esmini/tests/config_esmini_open_loop.json rename to tests/config_esmini_open_loop.json diff --git a/plugins/minimator/tests/config_minimator_infinite.json b/tests/config_minimator_infinite.json similarity index 97% rename from plugins/minimator/tests/config_minimator_infinite.json rename to tests/config_minimator_infinite.json index 51610dd51..8d6687e47 100644 --- a/plugins/minimator/tests/config_minimator_infinite.json +++ b/tests/config_minimator_infinite.json @@ -1,7 +1,7 @@ { "version": "4", "include": [ - "${CLOE_ROOT}/tests/controller_basic.json" + "just_controller_basic.json" ], "defaults": { "controllers": [ diff --git a/plugins/minimator/tests/config_minimator_multi_agent_infinite.json b/tests/config_minimator_multi_agent_infinite.json similarity index 100% rename from plugins/minimator/tests/config_minimator_multi_agent_infinite.json rename to tests/config_minimator_multi_agent_infinite.json diff --git a/plugins/minimator/tests/config_minimator_smoketest.json b/tests/config_minimator_smoketest.json similarity index 100% rename from plugins/minimator/tests/config_minimator_smoketest.json rename to tests/config_minimator_smoketest.json diff --git a/tests/config_nop_infinite.json b/tests/config_nop_infinite.json index e29064ef0..d58449bcc 100644 --- a/tests/config_nop_infinite.json +++ b/tests/config_nop_infinite.json @@ -1,8 +1,8 @@ { "version": "4", "include": [ - "controller_virtue.json", - "controller_basic.json" + "just_controller_virtue.json", + "just_controller_basic.json" ], "simulators": [ { diff --git a/tests/config_nop_smoketest.json b/tests/config_nop_smoketest.json index 7c5086bd1..238708186 100644 --- a/tests/config_nop_smoketest.json +++ b/tests/config_nop_smoketest.json @@ -1,15 +1,12 @@ { "version": "4", - "include": [ "config_nop_infinite.json" ], - "server": { "listen": false, "listen_port": 23456 }, - "triggers": [ {"event": "virtue/failure", "action": "fail"}, { diff --git a/tests/controller_basic.json b/tests/controller_basic.json deleted file mode 100644 index ffbb760ac..000000000 --- a/tests/controller_basic.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "4", - - "controllers": [ - { - "binding": "basic", - "vehicle": "default" - } - ], - - "triggers": [ - { - "event": "start", - "action": { - "name": "bundle", - "actions": [ - "basic/hmi=!enable" - ] - } - }, - { "event": "next=1", "action": "basic/hmi=enable" }, - { "event": "time=5", "action": "basic/hmi=resume" }, - { "event": "time=5.5", "action": "basic/hmi=!resume" }, - { - "label": "Push and release basic/hmi=plus", - "event": "time=6", - "action": { - "name": "insert", - "triggers": [ - { "event": "next", "action": "basic/hmi=plus" }, - { "event": "next=1", "action": "basic/hmi=!plus" } - ] - } - } - ] -} diff --git a/plugins/esmini/tests/controller_basic_aeb.json b/tests/controller_basic_aeb.json similarity index 100% rename from plugins/esmini/tests/controller_basic_aeb.json rename to tests/controller_basic_aeb.json diff --git a/engine/tests/controller_basic.json b/tests/just_controller_basic.json similarity index 100% rename from engine/tests/controller_basic.json rename to tests/just_controller_basic.json diff --git a/engine/tests/controller_virtue.json b/tests/just_controller_virtue.json similarity index 100% rename from engine/tests/controller_virtue.json rename to tests/just_controller_virtue.json diff --git a/tests/debug_callgrind.json b/tests/option_debug_callgrind.json similarity index 100% rename from tests/debug_callgrind.json rename to tests/option_debug_callgrind.json diff --git a/tests/setup_bats.bash b/tests/setup_bats.bash index c9f04feaa..093440a72 100644 --- a/tests/setup_bats.bash +++ b/tests/setup_bats.bash @@ -1,5 +1,8 @@ #!/usr/bin/env bats +# All tests are run from within the tests/ directory. +cd "${BATS_TEST_DIRNAME}" + # The path to use whenever we need a temporary registry. Whenever we use this, we # probably want to specify the `--write-output` flag too, otherwise nothing will # be written to the registry. @@ -45,3 +48,15 @@ test_plugin_exists() { cloe-engine usage "${plugin}" &>/dev/null } + +require_program() { + if ! type $1 &>/dev/null; then + skip "required program not present: $1" + fi +} + +require_engine_with_server() { + if ! cloe-engine version | grep -F "server: true" &>/dev/null; then + skip "required engine option not set: server" + fi +} diff --git a/tests/test_conanfile_external.py b/tests/test_conanfile_external.py new file mode 100644 index 000000000..0ac725fe5 --- /dev/null +++ b/tests/test_conanfile_external.py @@ -0,0 +1,54 @@ +# mypy: ignore-errors +# pylint: skip-file +# +# NOTE: +# This filename needs to not match ^conanfile_*.py$ in order to not be +# used in the automatic smoketest test suite. + +from pathlib import Path + +from conan import ConanFile +from conan.tools import files, scm + +required_conan_version = ">=1.52.0" + + +class CloeSuperbuildWithExternalTest(ConanFile): + """ + This recipe shows how to combine the cloe package -- which provides + cloe-runtime, etc. -- with packages that depend on these provided + packages. + + NOTE: + This test is disabled until the use-case works with Conan. + See "Known Issues" in the README.md of the repository. + """ + + python_requires = "cloe-launch-profile/[>=0.20.0]@cloe/develop" + python_requires_extend = "cloe-launch-profile.Base" + + name = "cloe-superbuild-test" + license = "Apache-2.0" + url = "https://github.com/eclipse/cloe" + description = "Closed-loop automated driving simulation environment" + topics = ["simulation"] + settings = "os", "compiler", "build_type", "arch" + + @property + def cloe_launch_env(self): + return { + "CLOE_ENGINE_WITH_SERVER": "1" if self.options["cloe"].engine_server else "0", + "CLOE_LOG_LEVEL": "debug", + "CLOE_STRICT_MODE": "1", + "CLOE_WRITE_OUTPUT": "0", + "CLOE_ROOT": Path(self.recipe_folder) / "..", + } + + def set_version(self): + self.version = self.project_version("../VERSION") + + def requirements(self): + self.requires(f"cloe/{self.version}@cloe/develop") + self.requires(f"cloe-plugin-example-external/{self.version}@cloe/develop") + self.requires("esmini-data/2.37.4@cloe/stable") + self.requires("fmt/9.1.0", override=True) diff --git a/engine/tests/test_engine.bats b/tests/test_engine.bats similarity index 88% rename from engine/tests/test_engine.bats rename to tests/test_engine.bats index b25e155bc..1f1640387 100755 --- a/engine/tests/test_engine.bats +++ b/tests/test_engine.bats @@ -1,13 +1,7 @@ #!/usr/bin/env bats -cd "${BATS_TEST_DIRNAME}" -export CLOE_ROOT="${BATS_TEST_DIRNAME}/../.." -load "${CLOE_ROOT}/tests/setup_bats.bash" -load "${CLOE_ROOT}/tests/setup_testname.bash" - -check_engine_with_server() { - cloe-engine version | grep -F "server: true" &>/dev/null -} +load setup_bats +load setup_testname @test "$(testname 'Expect schema equality' 'test_engine_json_schema.json' '4d368665-b666-4289-8a7a-b76ca53db688')" { # Note: you will have to update the schema files every time you change the schema, @@ -16,25 +10,24 @@ check_engine_with_server() { # cloe-launch -vv exec conanfile.py -- usage -j > tests/test_engine_json_schema.json # # Then use git diff to check that the changes make sense and are what you expect. - if ! type diff &>/dev/null; then - skip "required program diff not present" - fi + require_program diff diff <(cloe-engine usage -j 2>/dev/null) test_engine_json_schema.json } @test "$(testname 'Expect stack equality' 'test_engine_nop_smoketest_dump.json' '3b23bb69-b249-49c8-8b4c-2fa993d8677e')" { - if ! type diff &>/dev/null; then - skip "required program diff not present" - fi + require_program diff # The plugin section and the registry section have path references, which # are not reproducible, so we need to rewrite them and delete these lines. # This does not negatively affect the validity of the test. reference_file=test_engine_nop_smoketest_dump.json diff <(cloe-engine dump config_nop_smoketest.json | - sed -r -e 's#"/.*\/.*.conan/data/([^/]+)/.*"#"/.../\1/.../"#' -e "\\#(${HOME-/root}|${CONAN_USER_HOME-/cloe_dev})/.*#d") \ - ${reference_file} + sed -r -e '#"/.*\/.*.conan/data/([^/]+)/.*"#d' \ + -e '\#\.\.\./cloe-engine/\.\.\.#d' \ + -e "\\#(${HOME-/root}|${CONAN_USER_HOME-/cloe_dev})/.*#d" \ + ) \ + ${reference_file} } @test "$(testname 'Expect check success' 'test_engine_smoketest.json' '20c3f11e-4a93-4066-b61e-d485be5c8979')" { @@ -71,12 +64,9 @@ check_engine_with_server() { } @test "$(testname 'Expect run success' 'test_engine_curl_succeed.json' 'f473cb96-7f2e-4ac1-801a-fd93343f6e24')" { - if ! type curl &>/dev/null; then - skip "required program curl not present" - fi - if ! check_engine_with_server; then - skip "server component disabled" - fi + require_program curl + require_engine_with_server + cloe-engine run test_engine_curl_succeed.json } @@ -158,8 +148,10 @@ check_engine_with_server() { } @test "$(testname 'Expect check failure' 'test_engine_unavailable_*.json' '6cf4ded3-8a57-4dee-afac-bb03a8068e41')" { - run cloe-engine -l info check -d test_engine_unavailable_*.json - test $status -eq $CLOE_EXIT_UNKNOWN + for file in test_engine_unavailable_*.json; do + run cloe-engine -l info check "$file" + test $status -eq $CLOE_EXIT_UNKNOWN + done } @test "$(testname 'Expect check failure' 'test_engine_include_nonexistent.json' 'bad115cc-0397-48e6-9a51-bdcfeaf6b024')" { @@ -186,17 +178,13 @@ check_engine_with_server() { } @test "$(testname 'Expect check success' 'test_engine_keep_alive.json' '254544dc-c17a-4a5c-8685-723ed1c758cf')" { - if ! type kill &>/dev/null; then - skip "required program kill not present" - fi + require_program kill cloe-engine check test_engine_keep_alive.json } @test "$(testname 'Expect run success' 'test_engine_keep_alive.json' '0c5ace05-f5ca-4615-9c14-62a75b69651a')" { - if ! type kill &>/dev/null; then - skip "required program kill not present" - fi + require_program kill cloe-engine run test_engine_keep_alive.json } @@ -248,12 +236,8 @@ check_engine_with_server() { } @test "$(testname 'Expect run success' 'test_engine_pause.json' '845e3c9b-2a6d-469a-93a7-67fe9531c81e')" { - if ! type curl &>/dev/null; then - skip "required program curl not present" - fi - if ! check_engine_with_server; then - skip "server component disabled" - fi + require_program curl + require_engine_with_server cloe-engine run test_engine_pause.json } @@ -290,12 +274,8 @@ check_engine_with_server() { } @test "$(testname 'Expect run syskill' 'test_engine_watchdog.json' '058ff9b7-98dc-4583-8e80-c70e9c5e1f4e')" { - if ! type curl &>/dev/null; then - skip "required program curl not present" - fi - if ! check_engine_with_server; then - skip "server component disabled" - fi + require_program curl + require_engine_with_server cloe-engine check test_engine_watchdog.json @@ -305,13 +285,13 @@ check_engine_with_server() { } @test "$(testname 'Expect check/run success' 'test_engine_smoketest.json [ts=5ms]' '1a31022c-e20c-4a9e-9373-ad54a3729442')" { - local timestep_stack="${CLOE_ROOT}/tests/option_timestep_5.json" + local timestep_stack="option_timestep_5.json" cloe-engine check test_engine_smoketest.json "${timestep_stack}" cloe-engine run test_engine_smoketest.json "${timestep_stack}" } @test "$(testname 'Expect check/run success' 'test_engine_smoketest.json [ts=60ms]' 'e7957fa0-1145-4458-b665-eec51c1f0da5')" { - local timestep_stack="${CLOE_ROOT}/tests/option_timestep_60.json" + local timestep_stack="option_timestep_60.json" cloe-engine check test_engine_smoketest.json "${timestep_stack}" cloe-engine run test_engine_smoketest.json "${timestep_stack}" } diff --git a/engine/tests/test_engine_bad_logging.json b/tests/test_engine_bad_logging.json similarity index 100% rename from engine/tests/test_engine_bad_logging.json rename to tests/test_engine_bad_logging.json diff --git a/engine/tests/test_engine_curl_succeed.json b/tests/test_engine_curl_succeed.json similarity index 77% rename from engine/tests/test_engine_curl_succeed.json rename to tests/test_engine_curl_succeed.json index e9fccb776..c07c75bb2 100644 --- a/engine/tests/test_engine_curl_succeed.json +++ b/tests/test_engine_curl_succeed.json @@ -16,15 +16,15 @@ {"event": "start", "action": "realtime_factor=-1"}, { "label": "Insert the stop trigger via curl to test the web server.", - "event": "time=10", + "event": "time=1", "action": { "name": "command", - "command": "echo '{\"event\": \"time=60\", \"action\": \"succeed\"}' | curl -d @- http://localhost:23456/api/triggers/input" + "command": "echo '{\"event\": \"time=2\", \"action\": \"succeed\"}' | curl -d @- http://localhost:23456/api/triggers/input" } }, { "label": "If we get this far, then the curl command didn't work.", - "event": "time=120", + "event": "time=3", "action": { "name": "bundle", "actions": [ diff --git a/engine/tests/test_engine_empty.json b/tests/test_engine_empty.json similarity index 100% rename from engine/tests/test_engine_empty.json rename to tests/test_engine_empty.json diff --git a/engine/tests/test_engine_fail_trigger.json b/tests/test_engine_fail_trigger.json similarity index 100% rename from engine/tests/test_engine_fail_trigger.json rename to tests/test_engine_fail_trigger.json diff --git a/engine/tests/test_engine_hook_failure.json b/tests/test_engine_hook_failure.json similarity index 100% rename from engine/tests/test_engine_hook_failure.json rename to tests/test_engine_hook_failure.json diff --git a/engine/tests/test_engine_hook_invalid.json b/tests/test_engine_hook_invalid.json similarity index 100% rename from engine/tests/test_engine_hook_invalid.json rename to tests/test_engine_hook_invalid.json diff --git a/engine/tests/test_engine_hook_noexec.json b/tests/test_engine_hook_noexec.json similarity index 100% rename from engine/tests/test_engine_hook_noexec.json rename to tests/test_engine_hook_noexec.json diff --git a/engine/tests/test_engine_hook_ok.json b/tests/test_engine_hook_ok.json similarity index 100% rename from engine/tests/test_engine_hook_ok.json rename to tests/test_engine_hook_ok.json diff --git a/engine/tests/test_engine_ignore.json b/tests/test_engine_ignore.json similarity index 100% rename from engine/tests/test_engine_ignore.json rename to tests/test_engine_ignore.json diff --git a/engine/tests/test_engine_include_nonexistent.json b/tests/test_engine_include_nonexistent.json similarity index 100% rename from engine/tests/test_engine_include_nonexistent.json rename to tests/test_engine_include_nonexistent.json diff --git a/engine/tests/test_engine_include_self.json b/tests/test_engine_include_self.json similarity index 100% rename from engine/tests/test_engine_include_self.json rename to tests/test_engine_include_self.json diff --git a/engine/tests/test_engine_incomplete.json b/tests/test_engine_incomplete.json similarity index 100% rename from engine/tests/test_engine_incomplete.json rename to tests/test_engine_incomplete.json diff --git a/engine/tests/test_engine_invalid_trigger.json b/tests/test_engine_invalid_trigger.json similarity index 100% rename from engine/tests/test_engine_invalid_trigger.json rename to tests/test_engine_invalid_trigger.json diff --git a/engine/tests/test_engine_json_schema.json b/tests/test_engine_json_schema.json similarity index 68% rename from engine/tests/test_engine_json_schema.json rename to tests/test_engine_json_schema.json index 3c1a90679..c2149ffdd 100644 --- a/engine/tests/test_engine_json_schema.json +++ b/tests/test_engine_json_schema.json @@ -252,6 +252,59 @@ ], "type": "object" }, + { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "components": { + "description": "array of components to be extracted", + "items": { + "type": "string" + }, + "type": "array" + }, + "output_file": { + "description": "file path to write groundtruth output to", + "type": "string" + }, + "output_type": { + "description": "type of output file to write", + "enum": [ + "json.bz2", + "json.gz", + "json.zip", + "json", + "msgpack.bz2", + "msgpack.gz", + "msgpack.zip", + "msgpack" + ], + "type": "string" + } + }, + "type": "object" + }, + "binding": { + "const": "gndtruth_extractor", + "description": "name of factory" + }, + "name": { + "description": "globally unique identifier for controller", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", + "type": "string" + }, + "vehicle": { + "description": "vehicle controller is assigned to", + "type": "string" + } + }, + "required": [ + "binding" + ], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -1059,6 +1112,189 @@ "description": "simulator configuration", "items": { "oneOf": [ + { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "headless": { + "description": "run esmini without viewer", + "type": "boolean" + }, + "scenario": { + "description": "absolute path to open scenario file", + "type": "string" + }, + "vehicles": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "closed_loop": { + "description": "control the esmini vehicle", + "type": "boolean" + }, + "filter_distance": { + "description": "filter distance for ground truth data", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + } + }, + "type": "object" + }, + "description": "vehicle configuration like sensors and component mapping", + "type": "object" + }, + "write_images": { + "description": "save an image for each step", + "type": "boolean" + } + }, + "type": "object" + }, + "binding": { + "const": "esmini", + "description": "name of factory" + }, + "name": { + "description": "globally unique identifier for simulator", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", + "type": "string" + } + }, + "required": [ + "binding" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "vehicles": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "ego_sensor_mockup": { + "additionalProperties": false, + "description": "Ego sensor mockup configuration", + "properties": { + "ego_object": { + "additionalProperties": false, + "description": "Ego object configuration in world coordinates", + "properties": { + "position": { + "additionalProperties": false, + "description": "Object position coordinates (x,y,z)", + "properties": { + "x": { + "description": "Object position x axis", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "y": { + "description": "Object position y axis", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "z": { + "description": "Object position z axis", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + } + }, + "type": "object" + }, + "velocity": { + "description": "Object longitudinal velocity", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "object_sensor_mockup": { + "additionalProperties": false, + "description": "Object sensor mockup configuration", + "properties": { + "objects": { + "description": "Array of object configuration relative to ego vehicle", + "items": { + "additionalProperties": false, + "properties": { + "position": { + "additionalProperties": false, + "description": "Object position coordinates (x,y,z)", + "properties": { + "x": { + "description": "Object position x axis", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "y": { + "description": "Object position y axis", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "z": { + "description": "Object position z axis", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + } + }, + "type": "object" + }, + "velocity": { + "description": "Object longitudinal velocity", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "description": "list of vehicle names to make available", + "type": "object" + } + }, + "type": "object" + }, + "binding": { + "const": "minimator", + "description": "name of factory" + }, + "name": { + "description": "globally unique identifier for simulator", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", + "type": "string" + } + }, + "required": [ + "binding" + ], + "type": "object" + }, { "additionalProperties": false, "properties": { @@ -1202,6 +1438,327 @@ "components": { "additionalProperties": { "oneOf": [ + { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "enable": { + "description": "enable or disable component", + "type": "boolean" + }, + "frustum_culling": { + "description": "enable or disable frustum culling", + "type": "boolean" + } + }, + "type": "object" + }, + "binding": { + "const": "clothoid_fit", + "description": "name of factory" + }, + "from": { + "anyOf": [ + { + "description": "component input for binding", + "type": "string" + }, + { + "description": "component inputs for binding", + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "name": { + "description": "globally unique identifier for component", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", + "type": "string" + } + }, + "required": [ + "binding" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "frustum": { + "additionalProperties": false, + "description": "sensor frustum", + "properties": { + "clip_far": { + "description": "far clipping plane [m]", + "maximum": 1.7976931348623157e+308, + "minimum": 0.0, + "type": "number" + }, + "clip_near": { + "description": "near clipping plane [m]", + "maximum": 1.7976931348623157e+308, + "minimum": 0.0, + "type": "number" + }, + "fov_h": { + "description": "horizontal field of view [rad]", + "maximum": 6.283185307179586, + "minimum": 0.0, + "type": "number" + }, + "fov_v": { + "description": "vertical field of view [rad]", + "maximum": 6.283185307179586, + "minimum": 0.0, + "type": "number" + }, + "offset_h": { + "description": "horizontal field-of-view offset [rad]", + "maximum": 6.283185307179586, + "minimum": -6.283185307179586, + "type": "number" + }, + "offset_v": { + "description": "vertical field-of-view offset [rad]", + "maximum": 6.283185307179586, + "minimum": -6.283185307179586, + "type": "number" + } + }, + "type": "object" + }, + "reference_frame": { + "additionalProperties": false, + "description": "sensor frame of reference", + "properties": { + "pitch": { + "description": "pitch angle relative to ego reference frame [rad]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "roll": { + "description": "roll angle relative to ego reference frame [rad]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "x": { + "description": "x-position in ego reference frame [m]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "y": { + "description": "y-position in ego reference frame [m]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "yaw": { + "description": "yaw angle relative to ego reference frame [rad]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "z": { + "description": "z-position in ego reference frame [m]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + } + }, + "required": [ + "x", + "y", + "z", + "roll", + "pitch", + "yaw" + ], + "type": "object" + } + }, + "required": [ + "reference_frame", + "frustum" + ], + "type": "object" + }, + "binding": { + "const": "frustum_culling_lanes", + "description": "name of factory" + }, + "from": { + "anyOf": [ + { + "description": "component input for binding", + "type": "string" + }, + { + "description": "component inputs for binding", + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "name": { + "description": "globally unique identifier for component", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", + "type": "string" + } + }, + "required": [ + "binding" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": false, + "properties": { + "frustum": { + "additionalProperties": false, + "description": "sensor frustum", + "properties": { + "clip_far": { + "description": "far clipping plane [m]", + "maximum": 1.7976931348623157e+308, + "minimum": 0.0, + "type": "number" + }, + "clip_near": { + "description": "near clipping plane [m]", + "maximum": 1.7976931348623157e+308, + "minimum": 0.0, + "type": "number" + }, + "fov_h": { + "description": "horizontal field of view [rad]", + "maximum": 6.283185307179586, + "minimum": 0.0, + "type": "number" + }, + "fov_v": { + "description": "vertical field of view [rad]", + "maximum": 6.283185307179586, + "minimum": 0.0, + "type": "number" + }, + "offset_h": { + "description": "horizontal field-of-view offset [rad]", + "maximum": 6.283185307179586, + "minimum": -6.283185307179586, + "type": "number" + }, + "offset_v": { + "description": "vertical field-of-view offset [rad]", + "maximum": 6.283185307179586, + "minimum": -6.283185307179586, + "type": "number" + } + }, + "type": "object" + }, + "reference_frame": { + "additionalProperties": false, + "description": "sensor frame of reference", + "properties": { + "pitch": { + "description": "pitch angle relative to ego reference frame [rad]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "roll": { + "description": "roll angle relative to ego reference frame [rad]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "x": { + "description": "x-position in ego reference frame [m]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "y": { + "description": "y-position in ego reference frame [m]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "yaw": { + "description": "yaw angle relative to ego reference frame [rad]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + }, + "z": { + "description": "z-position in ego reference frame [m]", + "maximum": 1.7976931348623157e+308, + "minimum": -1.7976931348623157e+308, + "type": "number" + } + }, + "required": [ + "x", + "y", + "z", + "roll", + "pitch", + "yaw" + ], + "type": "object" + } + }, + "required": [ + "reference_frame", + "frustum" + ], + "type": "object" + }, + "binding": { + "const": "frustum_culling_objects", + "description": "name of factory" + }, + "from": { + "anyOf": [ + { + "description": "component input for binding", + "type": "string" + }, + { + "description": "component inputs for binding", + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "name": { + "description": "globally unique identifier for component", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$", + "type": "string" + } + }, + "required": [ + "binding" + ], + "type": "object" + }, { "additionalProperties": false, "properties": { diff --git a/engine/tests/test_engine_keep_alive.json b/tests/test_engine_keep_alive.json similarity index 100% rename from engine/tests/test_engine_keep_alive.json rename to tests/test_engine_keep_alive.json diff --git a/engine/tests/test_engine_namespaced_smoketest.json b/tests/test_engine_namespaced_smoketest.json similarity index 100% rename from engine/tests/test_engine_namespaced_smoketest.json rename to tests/test_engine_namespaced_smoketest.json diff --git a/engine/tests/test_engine_no_binding.json b/tests/test_engine_no_binding.json similarity index 100% rename from engine/tests/test_engine_no_binding.json rename to tests/test_engine_no_binding.json diff --git a/engine/tests/test_engine_no_vehicle.json b/tests/test_engine_no_vehicle.json similarity index 100% rename from engine/tests/test_engine_no_vehicle.json rename to tests/test_engine_no_vehicle.json diff --git a/engine/tests/test_engine_nop_smoketest_dump.json b/tests/test_engine_nop_smoketest_dump.json similarity index 95% rename from engine/tests/test_engine_nop_smoketest_dump.json rename to tests/test_engine_nop_smoketest_dump.json index bec76a9d2..6632ef48e 100644 --- a/engine/tests/test_engine_nop_smoketest_dump.json +++ b/tests/test_engine_nop_smoketest_dump.json @@ -31,11 +31,6 @@ "path": "${CLOE_SIMULATION_UUID}" }, "plugin_path": [ - "/.../cloe-plugin-basic/.../", - "/.../cloe-plugin-mocks/.../", - "/.../cloe-plugin-noisy-sensor/.../", - "/.../cloe-plugin-speedometer/.../", - "/.../cloe-plugin-virtue/.../" ], "plugins": { "allow_clobber": true, diff --git a/engine/tests/test_engine_optional_trigger.json b/tests/test_engine_optional_trigger.json similarity index 100% rename from engine/tests/test_engine_optional_trigger.json rename to tests/test_engine_optional_trigger.json diff --git a/engine/tests/test_engine_pause.json b/tests/test_engine_pause.json similarity index 100% rename from engine/tests/test_engine_pause.json rename to tests/test_engine_pause.json diff --git a/engine/tests/test_engine_replica_smoketest.bats b/tests/test_engine_replica_smoketest.bats similarity index 93% rename from engine/tests/test_engine_replica_smoketest.bats rename to tests/test_engine_replica_smoketest.bats index c0d19d35f..89db3d87f 100755 --- a/engine/tests/test_engine_replica_smoketest.bats +++ b/tests/test_engine_replica_smoketest.bats @@ -4,10 +4,8 @@ # configuration of a simulation results in roughly the same output # again, i.e., the simulation is reproducible. -cd "${BATS_TEST_DIRNAME}" -export CLOE_ROOT="${BATS_TEST_DIRNAME}/../.." -load "${CLOE_ROOT}/tests/setup_bats.bash" -load "${CLOE_ROOT}/tests/setup_testname.bash" +load setup_bats +load setup_testname teardown() { # Remove the temporary registry. diff --git a/engine/tests/test_engine_replica_smoketest.json b/tests/test_engine_replica_smoketest.json similarity index 100% rename from engine/tests/test_engine_replica_smoketest.json rename to tests/test_engine_replica_smoketest.json diff --git a/engine/tests/test_engine_smoketest.json b/tests/test_engine_smoketest.json similarity index 100% rename from engine/tests/test_engine_smoketest.json rename to tests/test_engine_smoketest.json diff --git a/tests/test_engine_start_stop.json b/tests/test_engine_start_stop.json new file mode 100644 index 000000000..c1ba40578 --- /dev/null +++ b/tests/test_engine_start_stop.json @@ -0,0 +1,26 @@ +{ + "version": "4", + "controllers": [ + { + "binding": "basic", + "vehicle": "default" + } + ], + "simulators": [ + { + "binding": "nop" + } + ], + "vehicles": [ + { + "name": "default", + "from": { + "simulator": "nop", + "index": 0 + } + } + ], + "triggers": [ + { "event": "start", "action": "succeed" } + ] +} diff --git a/engine/tests/test_engine_sticky_trigger.json b/tests/test_engine_sticky_trigger.json similarity index 100% rename from engine/tests/test_engine_sticky_trigger.json rename to tests/test_engine_sticky_trigger.json diff --git a/engine/tests/test_engine_stuck_controller.json b/tests/test_engine_stuck_controller.json similarity index 100% rename from engine/tests/test_engine_stuck_controller.json rename to tests/test_engine_stuck_controller.json diff --git a/engine/tests/test_engine_stuck_controller_continue.json b/tests/test_engine_stuck_controller_continue.json similarity index 100% rename from engine/tests/test_engine_stuck_controller_continue.json rename to tests/test_engine_stuck_controller_continue.json diff --git a/engine/tests/test_engine_unavailable_component.json b/tests/test_engine_unavailable_component.json similarity index 100% rename from engine/tests/test_engine_unavailable_component.json rename to tests/test_engine_unavailable_component.json diff --git a/engine/tests/test_engine_unavailable_controller.json b/tests/test_engine_unavailable_controller.json similarity index 100% rename from engine/tests/test_engine_unavailable_controller.json rename to tests/test_engine_unavailable_controller.json diff --git a/engine/tests/test_engine_unavailable_simulator.json b/tests/test_engine_unavailable_simulator.json similarity index 100% rename from engine/tests/test_engine_unavailable_simulator.json rename to tests/test_engine_unavailable_simulator.json diff --git a/engine/tests/test_engine_unknown_vehicle.json b/tests/test_engine_unknown_vehicle.json similarity index 100% rename from engine/tests/test_engine_unknown_vehicle.json rename to tests/test_engine_unknown_vehicle.json diff --git a/engine/tests/test_engine_version_absent.json b/tests/test_engine_version_absent.json similarity index 100% rename from engine/tests/test_engine_version_absent.json rename to tests/test_engine_version_absent.json diff --git a/engine/tests/test_engine_version_wrong.json b/tests/test_engine_version_wrong.json similarity index 100% rename from engine/tests/test_engine_version_wrong.json rename to tests/test_engine_version_wrong.json diff --git a/engine/tests/test_engine_watchdog.json b/tests/test_engine_watchdog.json similarity index 100% rename from engine/tests/test_engine_watchdog.json rename to tests/test_engine_watchdog.json diff --git a/plugins/esmini/tests/test_esmini.bats b/tests/test_esmini.bats similarity index 80% rename from plugins/esmini/tests/test_esmini.bats rename to tests/test_esmini.bats index 2fa1fc4a5..64fcc8cca 100755 --- a/plugins/esmini/tests/test_esmini.bats +++ b/tests/test_esmini.bats @@ -1,9 +1,7 @@ #!/usr/bin/env bats -cd "${BATS_TEST_DIRNAME}" -export CLOE_ROOT="${BATS_TEST_DIRNAME}/../../.." -load "${CLOE_ROOT}/tests/setup_bats.bash" -load "${CLOE_ROOT}/tests/setup_testname.bash" +load setup_bats +load setup_testname @test "$(testname 'Expect check success' 'test_esmini_open_loop.json' '05be11dc-1904-4f5e-bed7-531adf51a55c')" { cloe-engine check test_esmini_open_loop.json diff --git a/plugins/esmini/tests/test_esmini_closed_loop.json b/tests/test_esmini_closed_loop.json similarity index 100% rename from plugins/esmini/tests/test_esmini_closed_loop.json rename to tests/test_esmini_closed_loop.json diff --git a/plugins/esmini/tests/test_esmini_open_loop.json b/tests/test_esmini_open_loop.json similarity index 100% rename from plugins/esmini/tests/test_esmini_open_loop.json rename to tests/test_esmini_open_loop.json diff --git a/plugins/gndtruth_extractor/tests/test_gndtruth.bats b/tests/test_gndtruth.bats similarity index 93% rename from plugins/gndtruth_extractor/tests/test_gndtruth.bats rename to tests/test_gndtruth.bats index 582a5c50a..a5681b801 100755 --- a/plugins/gndtruth_extractor/tests/test_gndtruth.bats +++ b/tests/test_gndtruth.bats @@ -1,9 +1,7 @@ #!/usr/bin/env bats -cd "${BATS_TEST_DIRNAME}" -export CLOE_ROOT="${BATS_TEST_DIRNAME}/../../.." -load "${CLOE_ROOT}/tests/setup_bats.bash" -load "${CLOE_ROOT}/tests/setup_testname.bash" +load setup_bats +load setup_testname # Usage: FILENAME=$(mktemp_gndtruth_out SUFFIX) # diff --git a/plugins/gndtruth_extractor/tests/config_minimator_smoketest.json b/tests/test_gndtruth_config.json similarity index 95% rename from plugins/gndtruth_extractor/tests/config_minimator_smoketest.json rename to tests/test_gndtruth_config.json index 7edadbd8c..b6eaba7d3 100644 --- a/plugins/gndtruth_extractor/tests/config_minimator_smoketest.json +++ b/tests/test_gndtruth_config.json @@ -1,7 +1,7 @@ { "version": "4", "include": [ - "${CLOE_ROOT}/tests/controller_basic.json" + "${CLOE_ROOT}/tests/just_controller_basic.json" ], "simulators": [ { diff --git a/plugins/gndtruth_extractor/tests/test_gndtruth_invalid_file.json b/tests/test_gndtruth_invalid_file.json similarity index 86% rename from plugins/gndtruth_extractor/tests/test_gndtruth_invalid_file.json rename to tests/test_gndtruth_invalid_file.json index 3b27211a7..0aa552d9d 100644 --- a/plugins/gndtruth_extractor/tests/test_gndtruth_invalid_file.json +++ b/tests/test_gndtruth_invalid_file.json @@ -1,7 +1,7 @@ { "version": "4", "include": [ - "config_minimator_smoketest.json" + "test_gndtruth_config.json" ], "controllers": [ { diff --git a/plugins/gndtruth_extractor/tests/test_gndtruth_smoketest.json b/tests/test_gndtruth_smoketest.json similarity index 96% rename from plugins/gndtruth_extractor/tests/test_gndtruth_smoketest.json rename to tests/test_gndtruth_smoketest.json index c57168a79..bc1df7e3b 100644 --- a/plugins/gndtruth_extractor/tests/test_gndtruth_smoketest.json +++ b/tests/test_gndtruth_smoketest.json @@ -1,7 +1,7 @@ { "version": "4", "include": [ - "config_minimator_smoketest.json" + "test_gndtruth_config.json" ], "controllers": [ { diff --git a/plugins/gndtruth_extractor/tests/test_gndtruth_smoketest_output.json b/tests/test_gndtruth_smoketest_output.json similarity index 100% rename from plugins/gndtruth_extractor/tests/test_gndtruth_smoketest_output.json rename to tests/test_gndtruth_smoketest_output.json diff --git a/plugins/gndtruth_extractor/tests/test_gndtruth_smoketest_output.msgpack b/tests/test_gndtruth_smoketest_output.msgpack similarity index 100% rename from plugins/gndtruth_extractor/tests/test_gndtruth_smoketest_output.msgpack rename to tests/test_gndtruth_smoketest_output.msgpack diff --git a/plugins/minimator/tests/test_minimator.bats b/tests/test_minimator.bats similarity index 79% rename from plugins/minimator/tests/test_minimator.bats rename to tests/test_minimator.bats index 8699ec68b..b1b6570f8 100755 --- a/plugins/minimator/tests/test_minimator.bats +++ b/tests/test_minimator.bats @@ -1,9 +1,7 @@ #!/usr/bin/env bats -cd "${BATS_TEST_DIRNAME}" -export CLOE_ROOT="${BATS_TEST_DIRNAME}/../../.." -load "${CLOE_ROOT}/tests/setup_bats.bash" -load "${CLOE_ROOT}/tests/setup_testname.bash" +load setup_bats +load setup_testname @test "$(testname 'Expect check success' 'test_minimator_smoketest.json' 'c7a427e7-eb2b-4ae7-85ec-a35b7540d4aa')" { cloe-engine check test_minimator_smoketest.json @@ -14,13 +12,13 @@ load "${CLOE_ROOT}/tests/setup_testname.bash" } @test "$(testname 'Expect check/run success' 'test_minimator_smoketest.json [ts=5ms]' '57254185-5480-4859-b2a5-6c3a211a22e0')" { - local timestep_stack="${CLOE_ROOT}/tests/option_timestep_5.json" + local timestep_stack="option_timestep_5.json" cloe-engine check test_minimator_smoketest.json "${timestep_stack}" cloe-engine run test_minimator_smoketest.json "${timestep_stack}" } @test "$(testname 'Expect check/run success' 'test_minimator_smoketest.json [ts=60ms]' 'a0d4982f-8c02-4759-bc88-cc30a1ccbbf0')" { - local timestep_stack="${CLOE_ROOT}/tests/option_timestep_60.json" + local timestep_stack="option_timestep_60.json" cloe-engine check test_minimator_smoketest.json "${timestep_stack}" cloe-engine run test_minimator_smoketest.json "${timestep_stack}" } diff --git a/plugins/minimator/tests/test_minimator_multi_agent_smoketest.json b/tests/test_minimator_multi_agent_smoketest.json similarity index 93% rename from plugins/minimator/tests/test_minimator_multi_agent_smoketest.json rename to tests/test_minimator_multi_agent_smoketest.json index b3b2f9e19..26bda0f9f 100644 --- a/plugins/minimator/tests/test_minimator_multi_agent_smoketest.json +++ b/tests/test_minimator_multi_agent_smoketest.json @@ -2,7 +2,7 @@ "version": "4", "include": [ "config_minimator_multi_agent_infinite.json", - "${CLOE_ROOT}/tests/triggers_multi_agent.json" + "triggers_multi_agent.json" ], "server": { "listen": false, diff --git a/plugins/minimator/tests/test_minimator_smoketest.json b/tests/test_minimator_smoketest.json similarity index 100% rename from plugins/minimator/tests/test_minimator_smoketest.json rename to tests/test_minimator_smoketest.json diff --git a/plugins/virtue/tests/test_virtue.bats b/tests/test_virtue.bats similarity index 83% rename from plugins/virtue/tests/test_virtue.bats rename to tests/test_virtue.bats index b9f61b0a2..c4b654bdb 100755 --- a/plugins/virtue/tests/test_virtue.bats +++ b/tests/test_virtue.bats @@ -1,9 +1,7 @@ #!/usr/bin/env bats -cd "${BATS_TEST_DIRNAME}" -export CLOE_ROOT="${BATS_TEST_DIRNAME}/../../.." -load "${CLOE_ROOT}/tests/setup_bats.bash" -load "${CLOE_ROOT}/tests/setup_testname.bash" +load setup_bats +load setup_testname @test "$(testname 'Expect check success' 'test_virtue_missing_lanes_fail.json' 'd9072cc3-62f3-4f11-bf9e-b514fea67e4b')" { cloe-engine check test_virtue_missing_lanes_fail.json diff --git a/plugins/virtue/tests/test_virtue_missing_lanes_fail.json b/tests/test_virtue_missing_lanes_fail.json similarity index 92% rename from plugins/virtue/tests/test_virtue_missing_lanes_fail.json rename to tests/test_virtue_missing_lanes_fail.json index fdfbf9297..60be5ba93 100644 --- a/plugins/virtue/tests/test_virtue_missing_lanes_fail.json +++ b/tests/test_virtue_missing_lanes_fail.json @@ -1,7 +1,7 @@ { "version": "4", "include": [ - "${CLOE_ROOT}/tests/config_nop_infinite.json" + "config_nop_infinite.json" ], "defaults": { "controllers": [ diff --git a/plugins/virtue/tests/test_virtue_missing_lanes_pass.json b/tests/test_virtue_missing_lanes_pass.json similarity index 84% rename from plugins/virtue/tests/test_virtue_missing_lanes_pass.json rename to tests/test_virtue_missing_lanes_pass.json index eb76d9f81..55d90d104 100644 --- a/plugins/virtue/tests/test_virtue_missing_lanes_pass.json +++ b/tests/test_virtue_missing_lanes_pass.json @@ -1,7 +1,7 @@ { "version": "4", "include": [ - "${CLOE_ROOT}/plugins/minimator/tests/config_minimator_infinite.json" + "config_minimator_infinite.json" ], "server": { "listen": false diff --git a/vendor/esmini-data/conanfile.py b/vendor/esmini-data/conanfile.py index c285bc7e0..6572f14cf 100644 --- a/vendor/esmini-data/conanfile.py +++ b/vendor/esmini-data/conanfile.py @@ -13,6 +13,12 @@ class ESMiniData(ConanFile): description = "Basic OpenScenario player example data" topics = ("Environment Simulator", "OpenScenario", "OpenDrive") + # This package may not be built while all other packages are built + # because it is solely a runtime dependency. Because it only copies + # a few files, the only thing that may take a longer period of time + # is downloading the esmini archive. For now, this is acceptable. + build_policy = "missing" + def export_sources(self): files.export_conandata_patches(self) diff --git a/vendor/esmini/test_package/CMakeLists.txt b/vendor/esmini/test_package/CMakeLists.txt index 57e834a31..1dc1c7d17 100644 --- a/vendor/esmini/test_package/CMakeLists.txt +++ b/vendor/esmini/test_package/CMakeLists.txt @@ -1,7 +1,7 @@ -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(test_package LANGUAGES CXX) -find_package(esmini REQUIRED) +find_package(esmini REQUIRED QUIET) add_executable(${PROJECT_NAME} test_package.cpp) target_link_libraries(${PROJECT_NAME} diff --git a/vendor/open-simulation-interface/test_package/CMakeLists.txt b/vendor/open-simulation-interface/test_package/CMakeLists.txt index 27d995312..5bb5a5761 100644 --- a/vendor/open-simulation-interface/test_package/CMakeLists.txt +++ b/vendor/open-simulation-interface/test_package/CMakeLists.txt @@ -1,7 +1,7 @@ -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.15...3.27 FATAL_ERROR) project(test_package CXX) -find_package(open_simulation_interface REQUIRED CONFIG) +find_package(open_simulation_interface REQUIRED QUIET CONFIG) add_executable(${PROJECT_NAME} test_package.cpp) target_link_libraries(${PROJECT_NAME}