diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ef1fe2bb58b9dff343ab122fae309d9f7560244c..5488c958ab3caf2b431720d3c0be1cbab252bcbc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: rev: 22.3.0 hooks: - id: black - - repo: https://gitlab.com/PyCQA/flake8 + - repo: https://gitlab.com/pycqa/flake8.git rev: 3.9.2 hooks: - id: flake8 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4372671d5567c3438f3d5a7a6f81cd0440a44ef6..29d7b03a3422802d025ddf6539a090000873e0e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Other changes * Patch system now applies all patches in the `patch/` directory. Versioning for patches should be handled by git, not by require. +* The loop over `EPICSVERSION` in `driver.makefile` has been removed; various other cleanup has been performed. ## [4.0.0] diff --git a/require-ess/tools/driver.makefile b/require-ess/tools/driver.makefile index 71c43c9ffd320c428cf14d53785092c4800b92bf..1c792be0bb6d14cb4dd6f7f8d6ddbf3bd718bcde 100644 --- a/require-ess/tools/driver.makefile +++ b/require-ess/tools/driver.makefile @@ -15,20 +15,16 @@ # Therefore, it calls itself recursively. # # - First run: (see comment ## RUN 1) -# Find out what to build -# Iterate over all installed EPICS versions -# -# - Second run: (see comment ## RUN 2) # Find the sources etc. -# Include EPICS configuration files for this ${EPICSVERSION} -# Iterate over all target architectures (${T_A}) defined for this version +# Include EPICS configuration files for ${EPICSVERSION}, determined by ${EPICS_BASE} +# Iterate over all target architectures (${T_A}) defined. # -# - Third run: (see comment ## RUN 3) +# - Second run: (see comment ## RUN 2) # Check which target architectures to build. # Create O.${EPICSVERSION}_${T_A} subdirectories if necessary. # Change to O.${EPICSVERSION}_${T_A} subdirectories. # -# - Fourth run: (see comment ## RUN 4) +# - Third run: (see comment ## RUN 3) # Compile everything. # # Module names are derived from the directory name (unless overwritten @@ -54,8 +50,6 @@ # HEADERS # Header files to install (e.g. to be included by other drivers) # If not defined, all headers are for local use only. -# EXCLUDE_VERSIONS -# EPICS versions to skip. Usually 3.13 or 3.14 # ARCH_FILTER # Sub set of architectures to build for, e.g. %-ppc604 @@ -65,25 +59,26 @@ MAKEHOME:=$(dir $(lastword ${MAKEFILE_LIST})) USERMAKEFILE:=$(lastword $(filter-out $(lastword ${MAKEFILE_LIST}), ${MAKEFILE_LIST})) -##---## In E3, We only use ONE EPICS_BASE in order to COMPILE A MODULE -##---## -##---## In E3, EPICS_LOCATION is the EPICS BASE /testing/epics/base-MAJ.MIN.REV[.PATCH] +##---## In E3, We only use one version of EPICS base when compiling modules. +##---## EPICS_LOCATION is (by default) /epics/base-${EPICSVERSION} EPICS_LOCATION = +EPICS_BASE=${EPICS_LOCATION} +CONFIG=${EPICS_BASE}/configure + ##---## In E3, we extract BASE_VERSION from EPICS_LOCATION -E3_EPICS_VERSION:=$(patsubst base-%,%,$(notdir $(EPICS_LOCATION))) +EPICSVERSION:=$(patsubst base-%,%,$(notdir $(EPICS_LOCATION))) E3_SITEMODS_PATH = -BUILD_EPICS_VERSIONS = $(E3_EPICS_VERSION) ##---## BUILDCLASSES = Linux EPICS_MODULES = +OS_CLASS_LIST = $(BUILDCLASSES) -MODULE_LOCATION =${EPICS_MODULES}/$(or ${PRJ},$(error PRJ not defined))/$(or ${LIBVERSION},$(error LIBVERSION not defined)) - +MODULE= +PROJECT= +PRJ := $(strip $(or ${MODULE},${PROJECT})) -DOCUEXT = txt html htm doc pdf ps tex dvi gif jpg png -DOCUEXT += TXT HTML HTM DOC PDF PS TEX DVI GIF JPG PNG -DOCUEXT += template db dbt subs subst substitutions script +MODULE_LOCATION =${EPICS_MODULES}/$(or ${PRJ},$(error PRJ not defined))/$(or ${LIBVERSION},$(error LIBVERSION not defined)) # Override config here: -include ${MAKEHOME}/config @@ -100,7 +95,7 @@ RM = rm -f CP = cp MKDIR = mkdir -p -m 775 -# This is to allow for build numbers in recognized versions. First regex is for grep, second for sed. +# This is to allow for build numbers in recognized versions. VERSIONREGEX = [0-9]+\.[0-9]+\.[0-9]+(\+[0-9]+)? # Some generated file names: @@ -119,12 +114,31 @@ HEADERS= BASH_ENV= ENV= +# There is no 64 bit support before 3.14.12 +ifneq ($(filter %_64,$(EPICS_HOST_ARCH)),) +ifeq ($(wildcard $(EPICS_BASE)/lib/$(EPICS_HOST_ARCH)),) +EPICS_HOST_ARCH:=$(patsubst %_64,%,$(EPICS_HOST_ARCH)) +USR_CFLAGS_$(EPICS_HOST_ARCH) += -m32 +USR_CXXFLAGS_$(EPICS_HOST_ARCH) += -m32 +USR_LDFLAGS_$(EPICS_HOST_ARCH) += -m32 +endif +endif + # Default target is "build" for all versions. # Don't install anything (different from default EPICS make rules). default: build prebuild: +clean: + $(RMDIR) O.* + +O.%: + +$(MKDIR) $@ + +uninstall: + $(RMDIR) ${MODULE_LOCATION} + IGNOREFILES = .gitignore %: ${IGNOREFILES} ${IGNOREFILES}: @@ -163,165 +177,22 @@ select = $(strip $(call -select,$(strip $2),$1,$3)) str-eq = $(if $(subst x$1,,x$2),,t) # End of functions from https://github.com/markpiffer/gmtt.git -ifndef EPICSVERSION -## RUN 1 -# In source directory - -$(foreach v,$(sort $(basename ${BUILD_EPICS_VERSIONS})),$(eval EPICS_VERSIONS_$v=$(filter $v.%,${BUILD_EPICS_VERSIONS}))) - - -# Default module name is name of current directory. -# But in case of "src" or "snl", use parent directory instead. -# Avoid using environment variables for MODULE or PROJECT -MODULE= -PROJECT= -PRJDIR:=$(subst -,_,$(subst .,_,$(notdir $(patsubst %Lib,%,$(patsubst %/snl,%,$(patsubst %/src,%,${PWD})))))) -PRJ = $(strip $(or ${MODULE},${PROJECT},${PRJDIR})) -export PRJ - -OS_CLASS_LIST = $(BUILDCLASSES) -export OS_CLASS_LIST - -export ARCH_FILTER -export EXCLUDE_ARCHS -export MAKE_FIRST - -# Since we force modules to be in lowercase, we need to use the correct variables here -# e.g. MCoreUtils_E3_GIT_URL vs mcoreutils_E3_GIT_URL -${PRJ}_E3_GIT_URL := $(${PROJECT}_E3_GIT_URL) -export ${PRJ}_E3_GIT_URL -${PRJ}_E3_GIT_DESC := $(${PROJECT}_E3_GIT_DESC) -export ${PRJ}_E3_GIT_DESC -${PRJ}_E3_GIT_STATUS := $(${PROJECT}_E3_GIT_STATUS) -export ${PRJ}_E3_GIT_STATUS - -export SUBS -export TMPS - -clean:: - $(RMDIR) O.* - -uninstall: - $(RMDIR) ${MODULE_LOCATION} - -help: - @echo "usage:" - @for target in '' build '<EPICS version>' \ - install 'install.<EPICS version>' \ - uninstall 'uninstall.<EPICS version>' \ - installui uninstallui \ - clean help version; \ - do echo " make $$target"; \ - done - @echo "Makefile variables:(defaults) [comment]" - @echo " MODULE (${PRJ}) [from current directory name]" - @echo " PROJECT [older name for MODULE]" - @echo " SOURCES (*.c *.cc *.cpp *.st *.stt *.gt)" - @echo " DBDS (*.dbd)" - @echo " HEADERS () [only those to install]" - @echo " TEMPLATES (*.template *.db *.subs) [db files]" - @echo " SCRIPTS (*.cmd) [startup and other scripts]" - @echo " BINS () [programs to install]" - @echo " QT (qt/*) [QT user interfaces to install]" - @echo " EXCLUDE_VERSIONS () [versions not to build, e.g. 3.14]" - @echo " EXCLUDE_ARCHS () [target architectures not to build]" - @echo " ARCH_FILTER () [target architectures to build, e.g. SL6%]" - @echo " BUILDCLASSES (Linux)" - @echo " <module>_VERSION () [build against specific version of other module]" - -debug:: - @echo "===================== Pass 1 =====================" - @echo "BUILD_EPICS_VERSIONS = ${BUILD_EPICS_VERSIONS}" - @echo "BUILDCLASSES = ${BUILDCLASSES}" - @echo "LIBVERSION = ${LIBVERSION}" - @echo "VERSIONCHECKFILES = ${VERSIONCHECKFILES}" - @echo "ARCH_FILTER = ${ARCH_FILTER}" - @echo "PRJ = ${PRJ}" - -# Loop over all EPICS versions for second run. -MAKEVERSION = ${MAKE} -f ${USERMAKEFILE} LIBVERSION=${LIBVERSION} - -build install debug db_internal:: ${IGNOREFILES} - @+for VERSION in ${BUILD_EPICS_VERSIONS}; do ${MAKEVERSION} EPICSVERSION=$$VERSION $@; done - -define VERSIONRULES -$(1): ${IGNOREFILES} - @+for VERSION in $${EPICS_VERSIONS_$(1)}; do $${MAKEVERSION} EPICSVERSION=$$$$VERSION build; done - -%.$(1): ${IGNOREFILES} - @+for VERSION in $${EPICS_VERSIONS_$(1)}; do $${MAKEVERSION} EPICSVERSION=$$$$VERSION $${@:%.$(1)=%}; done -endef -$(foreach v,$(sort $(basename ${INSTALLED_EPICS_VERSIONS})),$(eval $(call VERSIONRULES,$v))) - -# Handle cases where user requests one specific version: -# make <action>.<version> instead of make <action> or -# make <version> instead of make -# EPICS version must be installed but need not be in EPICS_VERSIONS -${INSTALLED_EPICS_VERSIONS}: ${IGNOREFILES} - +${MAKEVERSION} EPICSVERSION=$@ build - -${INSTALLED_EPICS_VERSIONS:%=build.%}: ${IGNOREFILES} - +${MAKEVERSION} EPICSVERSION=${@:build.%=%} build - -${INSTALLED_EPICS_VERSIONS:%=install.%}: ${IGNOREFILES} - +${MAKEVERSION} EPICSVERSION=${@:install.%=%} install - -${INSTALLED_EPICS_VERSIONS:%=debug.%}: - +${MAKEVERSION} EPICSVERSION=${@:debug.%=%} debug - -# Install user interfaces to global location. -# Keep a list of installed files in a hidden file for uninstall. -define INSTALL_UI_RULE -INSTALL_$(1)=$(2) -$(1)_FILES=$$(wildcard $$(or $${$(1)},$(3))) -installui: install$(1) -install$(1): uninstall$(1) - @$$(if $${$(1)_FILES},echo "Installing $(1) user interfaces";$$(MKDIR) $${INSTALL_$(1)}) - @$$(if $${$(1)_FILES},$(CP) -v -t $${INSTALL_$(1)} $${$(1)_FILES:%='%'}) - @$$(if $${$(1)_FILES},echo "$$(patsubst %,'%',$$(notdir $${$(1)_FILES}))" > $${INSTALL_$(1)}/.$${PRJ}-$$(LIBVERSION)-$(1).txt) - -uninstallui: uninstall$(1) -uninstall$(1): - @echo "Removing old $(1) user interfaces" - @$$(RM) -v $$(addprefix $${INSTALL_$(1)}/,$$(sort $$(patsubst %,'%',$$(notdir $${$(1)_FILES})) $$(shell cat $${INSTALL_$(1)}/.$${PRJ}-*.txt 2>/dev/null)) .$${PRJ}-*-$(1).txt) -endef - -# You can add more UI rules following this pattern: -#$(eval $(call INSTALL_UI_RULE,VARIABLE,installdir,sourcedefaultlocation)) -$(eval $(call INSTALL_UI_RULE,QT,${CONFIGBASE}/qt,qt/*)) - -else # EPICSVERSION -# EPICSVERSION defined -# Second or third run (see T_A branch below) - -EPICS_BASE=${EPICS_LOCATION} - -CONFIG=${EPICS_BASE}/configure - -# There is no 64 bit support before 3.14.12 -ifneq ($(filter %_64,$(EPICS_HOST_ARCH)),) -ifeq ($(wildcard $(EPICS_BASE)/lib/$(EPICS_HOST_ARCH)),) -EPICS_HOST_ARCH:=$(patsubst %_64,%,$(EPICS_HOST_ARCH)) -USR_CFLAGS_$(EPICS_HOST_ARCH) += -m32 -USR_CXXFLAGS_$(EPICS_HOST_ARCH) += -m32 -USR_LDFLAGS_$(EPICS_HOST_ARCH) += -m32 -endif -endif - - -${CONFIG}/CONFIG: - @echo "ERROR: EPICS release ${EPICSVERSION} not installed on this host." - # Some TOP and EPICS_BASE tweeking necessary to work around release check in 3.14.10+. EB:=${EPICS_BASE} TOP:=${EPICS_BASE} -include ${CONFIG}/CONFIG -BASE_CPPFLAGS= EPICS_BASE:=${EB} -COMMON_DIR = O.${EPICSVERSION}_Common + +${CONFIG}/CONFIG: + $(error EPICS release ${EPICSVERSION} not installed on this host.) + +# Variables that need to override data from ${CONFIG}/CONFIG +BASE_CPPFLAGS= + ifndef LEGACY_RSET USR_CPPFLAGS+=-DUSE_TYPED_RSET endif + SHRLIB_VERSION= # do not link *everything* with readline (and curses) COMMANDLINE_LIBRARY = @@ -332,18 +203,15 @@ CXXCMPLR=ANSI G++_ANSI = $(G++) -ansi OBJ=.o -O.%: - +$(MKDIR) $@ +COMMON_DIR = O.${EPICSVERSION}_Common ifndef T_A -## RUN 2 -# Target achitecture not yet defined -# but EPICSVERSION is already known. +## RUN 1 +# Target achitecture not yet defined, but EPICSVERSION is already known. # Still in source directory. -# Look for sources etc. -# Select target architectures to build. -# Export everything for third run: +# Look for sources etc., and select target architectures to build. +# Export everything for second run: AUTOSRCS := $(filter-out ~%,$(wildcard *.c *.cc *.cpp *.st *.stt *.gt)) SRCS = $(if ${SOURCES},$(filter-out -none-,${SOURCES}),${AUTOSRCS}) @@ -389,8 +257,9 @@ SCR += ${SCRIPTS_${EPICSVERSION}} export SCR # Filter architectures to build using EXCLUDE_ARCHS and ARCH_FILTER. -CROSS_COMPILER_TARGET_ARCHS := ${EPICS_HOST_ARCH} ${CROSS_COMPILER_TARGET_ARCHS} -CROSS_COMPILER_TARGET_ARCHS := $(filter-out $(addprefix %,${EXCLUDE_ARCHS}),$(filter-out $(addsuffix %,${EXCLUDE_ARCHS}),$(if ${ARCH_FILTER},$(filter ${ARCH_FILTER},${CROSS_COMPILER_TARGET_ARCHS}),${CROSS_COMPILER_TARGET_ARCHS}))) +ALL_ARCHS = ${EPICS_HOST_ARCH} ${CROSS_COMPILER_TARGET_ARCHS} +BUILD_ARCHS = $(filter-out $(addprefix %,${EXCLUDE_ARCHS}),$(filter-out $(addsuffix %,${EXCLUDE_ARCHS}),\ + $(if ${ARCH_FILTER},$(filter ${ARCH_FILTER},${ALL_ARCHS}),${ALL_ARCHS}))) SRCS_Linux = ${SOURCES_Linux} export SRCS_Linux @@ -400,48 +269,55 @@ db_internal: $(COMMON_DIR) -include $(COMMON_DIR)/*.db.d -define SUBS_EXPAND -vpath $(notdir $2) $(dir $2) -db_internal: $(COMMON_DIR)/$(notdir $(basename $2).db) +VPATH += $(dir $(TMPS)) +VPATH += $(dir $(SUBS)) -$(COMMON_DIR)/$(notdir $(basename $2).db): $(notdir $2) - @printf "Inflating database ... %44s >>> %40s \n" "$$^" "$$@" - $(QUIET)$(MSI) -D $$(USR_DBFLAGS) -o $(COMMON_DIR)/$$(notdir $$(basename $2).db) $1 $$^ > $(COMMON_DIR)/$$(notdir $$(basename $2).db).d - $(QUIET)$(MSI) $$(USR_DBFLAGS) -o $(COMMON_DIR)/$$(notdir $$(basename $2).db) $1 $$^ -endef +$(COMMON_DIR)/%.db: %.template + @printf "Inflating database ... %44s >>> %40s \n" "$^" "$@" + $(QUIET)$(MSI) -D $(USR_DBFLAGS) -o $(COMMON_DIR)/$(notdir $(basename $@).db) $^ > $(COMMON_DIR)/$(notdir $(basename $@).db).d + $(QUIET)$(MSI) $(USR_DBFLAGS) -o $(COMMON_DIR)/$(notdir $(basename $@).db) $^ -$(foreach file,$(SUBS),$(eval $(call SUBS_EXPAND,-S,$(file)))) -$(foreach file,$(TMPS),$(eval $(call SUBS_EXPAND,,$(file)))) +$(COMMON_DIR)/%.db: %.substitutions + @printf "Inflating database ... %44s >>> %40s \n" "$^" "$@" + $(QUIET)$(MSI) -D $(USR_DBFLAGS) -o $(COMMON_DIR)/$(notdir $(basename $@).db) -S $^ > $(COMMON_DIR)/$(notdir $(basename $@).db).d + $(QUIET)$(MSI) $(USR_DBFLAGS) -o $(COMMON_DIR)/$(notdir $(basename $@).db) -S $^ -install build debug:: $(MAKE_FIRST) +install build debug:: @echo "MAKING EPICS VERSION ${EPICSVERSION}" -uninstall:: - $(RMDIR) ${INSTALL_REV} - debug:: - @echo "===================== Pass 2: EPICSVERSION = $(EPICSVERSION) =====================" + @echo "===================== Pass 1 =====================" + @echo "BUILDCLASSES = ${BUILDCLASSES}" + @echo "LIBVERSION = ${LIBVERSION}" + @echo "PRJ = ${PRJ}" @echo "EPICS_BASE = ${EPICS_BASE}" - @echo "CROSS_COMPILER_TARGET_ARCHS = ${CROSS_COMPILER_TARGET_ARCHS}" + @echo "BUILD_ARCHS = ${BUILD_ARCHS}" + @echo "ARCH_FILTER = ${ARCH_FILTER}" @echo "EXCLUDE_ARCHS = ${EXCLUDE_ARCHS}" @echo "LIBVERSION = ${LIBVERSION}" # Loop over all architectures. install build debug:: $(COMMON_DIR) @+failed_builds=0; \ - for ARCH in ${CROSS_COMPILER_TARGET_ARCHS}; do \ + for ARCH in ${BUILD_ARCHS}; do \ umask 002; echo MAKING ARCH $$ARCH; ${MAKE} -f ${USERMAKEFILE} T_A=$$ARCH $@ || ((failed_builds++)); \ done; \ ((failed_builds == 0)) +# This has to fit under .SECONDEXPANSION in order to catch TMPS and SUBS, which are typically defined +# _after_ driver.makefile is included. +.SECONDEXPANSION: +db_internal: $$(addprefix $(COMMON_DIR)/,$$(notdir $$(patsubst %.template,%.db,$$(TMPS)))) + +db_internal: $$(addprefix $(COMMON_DIR)/,$$(notdir $$(patsubst %.substitutions,%.db,$$(SUBS)))) else # T_A ifeq ($(filter O.%,$(notdir ${CURDIR})),) -## RUN 3 +## RUN 2 # Target architecture defined. -# Still in source directory, third run. +# Still in source directory, second run. # Add sources for specific epics types or architectures. ARCH_PARTS = ${T_A} $(subst -, ,${T_A}) ${OS_CLASS} @@ -514,7 +390,7 @@ $(foreach m,$(PROCESSED_MODULES),$(eval export $m_VERSION)) debug:: - @echo "===================== Pass 3: T_A = $(T_A) =====================" + @echo "===================== Pass 2: T_A = $(T_A) =====================" @echo "BINS = $(BINS)" @echo "REQ = $(REQ)" @echo "VLIBS = $(VLIBS)" @@ -575,8 +451,8 @@ ${PRJ}_GIT_STATUS := [ $(shell git status --porcelain 2> /dev/null | grep -v "\. export ${PRJ}_GIT_STATUS else # in O.* -## RUN 4 -# In O.* directory. +## RUN 3 +# In build directory. # Add macros like USR_CFLAGS_Linux. EXTENDED_VARS=INCLUDES CFLAGS CXXFLAGS CPPFLAGS CODE_CXXFLAGS LDFLAGS @@ -605,7 +481,7 @@ BASERULES=${EPICS_BASE}/configure/RULES INSTALL_REV = ${MODULE_LOCATION} INSTALL_BIN = ${INSTALL_REV}/bin/$(T_A) INSTALL_LIB = ${INSTALL_REV}/lib/$(T_A) -INSTALL_VLIB = ${INSTALL_REV}/lib/$(T_A)/vendor +INSTALL_VLIB = ${INSTALL_REV}/lib/$(T_A)/vendor INSTALL_INCLUDE = ${INSTALL_REV}/include INSTALL_DBD = ${INSTALL_REV}/dbd INSTALL_DB = ${INSTALL_REV}/db @@ -697,7 +573,7 @@ LIBOBJS += $(addsuffix $(OBJ),$(basename ${VERSIONFILE})) endif # MODULELIB debug:: - @echo "===================== Pass 4: Build directory =====================" + @echo "===================== Pass 3: Build directory =====================" @echo "BUILDCLASSES = ${BUILDCLASSES}" @echo "OS_CLASS = ${OS_CLASS}" @echo "MODULEDBD = ${MODULEDBD}" @@ -957,4 +833,3 @@ ${DEPFILE}: ${LIBOBJS} $(USERMAKEFILE) endif # In O.* directory endif # T_A defined -endif # EPICSVERSION defined diff --git a/tests/test_build.py b/tests/test_build.py index c7875620614cbe1345406739769abe4eef56867a..d599658cc22db464caf9ef33cbe039578089206b 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -1,6 +1,9 @@ +import os import re from pathlib import Path +import pytest + from .utils import run_ioc_get_output MODULE_VERSION = "0.0.0+0" @@ -467,3 +470,66 @@ def test_updated_template_files(wrapper): rc, *_ = wrapper.run_make("db_internal") assert rc == 0 assert db_file.read_text() == "record(ai, updated) {}" + + +def test_expand_db_files(wrapper): + """Test that the automated template/substitution file expansion works.""" + + wrapper.add_var_to_makefile("TMPS", "templates/a.template") + wrapper.add_var_to_makefile("SUBS", "b.substitutions") + wrapper.add_var_to_makefile("USR_DBFLAGS", "-I templates") + + template_dir = wrapper.module_dir / "templates" + template_dir.mkdir() + template_file = template_dir / "a.template" + template_file_contents = "record (ai, $(P)) {}" + template_file.write_text(template_file_contents) + + substitution_file = wrapper.module_dir / "b.substitutions" + substitution_file.write_text( + """file "a.template" +{ + pattern { P } + { "$(PREF)" } +} +""" + ) + + base_version = wrapper.get_env_var("EPICS_VERSION_NUMBER") + common_dir = wrapper.module_dir / f"O.{base_version}_Common" + + rc, *_ = wrapper.run_make("db_internal") + assert rc == 0 + + expanded_template_file = common_dir / "a.db" + assert expanded_template_file.read_text() == template_file_contents + + expanded_substitution_file = common_dir / "b.db" + assert expanded_substitution_file.read_text() == template_file_contents.replace( + "$(P)", "$(PREF)" + ) + + +@pytest.mark.parametrize( + "installed_archs, param, expected", + [ + ("foo bar baz foo-bar", "ARCH_FILTER=foo", ["foo"]), + ("foo", "EXCLUDE_ARCHS=foo", []), + ("foo-bar foo-baz baz baz-qux", "EXCLUDE_ARCHS=foo", ["baz", "baz-qux"]), + ], +) +def test_arch_filter(wrapper, installed_archs, param, expected): + arch_regex = re.compile(r"Pass 2: T_A =\s*([^\s]+)") + + wrapper.add_var_to_makefile( + "CROSS_COMPILER_TARGET_ARCHS", installed_archs, modifier="" + ) + + rc, o, _ = wrapper.run_make("debug", param) + + assert rc == 0 + + host_arch = os.getenv("EPICS_HOST_ARCH") + build_archs = [arch for arch in arch_regex.findall(o) if arch != host_arch] + + assert build_archs == expected