From 5b05a1f8227be58c702cc4e7c02eb90039feb728 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 5 Apr 2018 14:57:31 +1000 Subject: [PATCH] make: Build out of tree component srcs under component build dir Strips leading ../ when generating object file paths, keeps these in sync with the source files otherwise. This prevents object files landing in other directories, including outside the build directory, if the component_srcdirs start with ../ --- components/libsodium/test/component.mk | 8 ++--- make/common.mk | 10 ++++++- make/component_wrapper.mk | 41 ++++++++++++++++---------- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/components/libsodium/test/component.mk b/components/libsodium/test/component.mk index 75a54ae814..572099caed 100644 --- a/components/libsodium/test/component.mk +++ b/components/libsodium/test/component.mk @@ -3,6 +3,7 @@ # LS_TESTDIR := ../libsodium/test/default +LS_TEST_OBJDIR := libsodium/test/default ifdef TESTS_ALL $(info not linking libsodium tests, use 'TEST_COMPONENTS=libsodium' to test it) @@ -27,10 +28,9 @@ COMPONENT_OBJS := test_sodium.o define sodium_testcase # This would generate 'warning "main" redefined' warnings at runtime, which are # silenced here. Only other solution involves patching libsodium's cmptest.h. -$(LS_TESTDIR)/$(1).o: CFLAGS+=-Dxmain=$(1)_xmain -Dmain=$(1)_main -$(LS_TESTDIR)/$(1).o: CPPFLAGS+=-Wp,-w -ote: -COMPONENT_OBJS += $(LS_TESTDIR)/$(1).o +$(LS_TEST_OBJDIR)/$(1).o: CFLAGS+=-Dxmain=$(1)_xmain -Dmain=$(1)_main +$(LS_TEST_OBJDIR)/$(1).o: CPPFLAGS+=-Wp,-w +COMPONENT_OBJS += $(LS_TEST_OBJDIR)/$(1).o endef TEST_CASES := chacha20 aead_chacha20poly1305 box box2 ed25519_convert sign hash diff --git a/make/common.mk b/make/common.mk index ccee32278c..2eb0f0d3c0 100644 --- a/make/common.mk +++ b/make/common.mk @@ -62,7 +62,7 @@ endef # # example $(call resolvepath,$(CONFIG_PATH),$(CONFIG_DIR)) define resolvepath -$(foreach dir,$(1),$(if $(filter /%,$(dir)),$(dir),$(subst //,/,$(2)/$(dir)))) +$(abspath $(foreach dir,$(1),$(if $(filter /%,$(dir)),$(dir),$(subst //,/,$(2)/$(dir))))) endef @@ -86,3 +86,11 @@ endef define uniq $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1))) endef + +# macro to strip leading ../s from a path +# Given $(1) which is a directory, remove any leading ../s from it +# (recursively keeps removing ../ until not found) +# if the path contains nothing but ../.., a single . is returned (cwd) +define stripLeadingParentDirs +$(foreach path,$(1),$(if $(subst ..,,$(path)),$(if $(filter ../%,$(path)),$(call stripLeadingParentDirs,$(patsubst ../%,%,$(path))),$(path)),.)) +endef diff --git a/make/component_wrapper.mk b/make/component_wrapper.mk index ac36d73dec..b23872c798 100644 --- a/make/component_wrapper.mk +++ b/make/component_wrapper.mk @@ -129,6 +129,11 @@ COMPONENT_OBJS := $(foreach obj,$(COMPONENT_OBJS),$(if $(filter $(realpath $(obj # Remove duplicates COMPONENT_OBJS := $(call uniq,$(COMPONENT_OBJS)) +# Remove any leading ../ from paths, so everything builds inside build dir +COMPONENT_OBJS := $(call stripLeadingParentDirs,$(COMPONENT_OBJS)) + +# COMPONENT_OBJDIRS is COMPONENT_SRCDIRS with the same transform applied +COMPONENT_OBJDIRS := $(call stripLeadingParentDirs,$(COMPONENT_SRCDIRS)) # Object files with embedded binaries to add to the component library # Correspond to the files named in COMPONENT_EMBED_FILES & COMPONENT_EMBED_TXTFILES @@ -180,10 +185,10 @@ endef component_project_vars.mk:: $(details) "Building component project variables list $(abspath $@)" @echo '# Automatically generated build file. Do not edit.' > $@ - @echo 'COMPONENT_INCLUDES += $(call MakeVariablePath,$(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS)))' >> $@ + @echo 'COMPONENT_INCLUDES += $(call MakeVariablePath,$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS))))' >> $@ @echo 'COMPONENT_LDFLAGS += $(call MakeVariablePath,-L$(COMPONENT_BUILD_DIR) $(COMPONENT_ADD_LDFLAGS))' >> $@ @echo 'COMPONENT_LINKER_DEPS += $(call MakeVariablePath,$(call resolvepath,$(COMPONENT_ADD_LINKER_DEPS),$(COMPONENT_PATH)))' >> $@ - @echo 'COMPONENT_SUBMODULES += $(call MakeVariablePath,$(addprefix $(COMPONENT_PATH)/,$(COMPONENT_SUBMODULES)))' >> $@ + @echo 'COMPONENT_SUBMODULES += $(call MakeVariablePath,$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_SUBMODULES))))' >> $@ @echo 'COMPONENT_LIBRARIES += $(COMPONENT_NAME)' >> $@ @echo 'component-$(COMPONENT_NAME)-build: $(addprefix component-,$(addsuffix -build,$(COMPONENT_DEPENDS)))' >> $@ @@ -236,41 +241,45 @@ endef # This pattern is generated for each COMPONENT_SRCDIR to compile the files in it. define GenerateCompileTargets # $(1) - directory containing source files, relative to $(COMPONENT_PATH) - one of $(COMPONENT_SRCDIRS) +# $(2) - output build directory, which is $(1) with any leading ".."s converted to "."s to ensure output is always under build/ # -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_SRCDIRS) + +$(2)/%.o: $$(COMPONENT_PATH)/$(1)/%.c $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_OBJDIRS) $$(summary) CC $$(patsubst $$(PWD)/%,%,$$(CURDIR))/$$@ - $$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$< -o $$@ + $$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$(abspath $$<) -o $$@ $(call AppendSourceToDependencies,$$<,$$@) -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_SRCDIRS) +$(2)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_OBJDIRS) $$(summary) CXX $$(patsubst $$(PWD)/%,%,$$(CURDIR))/$$@ - $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$< -o $$@ + $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$(abspath $$<) -o $$@ $(call AppendSourceToDependencies,$$<,$$@) -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cc $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_SRCDIRS) +$(2)/%.o: $$(COMPONENT_PATH)/$(1)/%.cc $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_OBJDIRS) $$(summary) CXX $$(patsubst $$(PWD)/%,%,$$(CURDIR))/$$@ - $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$< -o $$@ + $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$(abspath $$<) -o $$@ $(call AppendSourceToDependencies,$$<,$$@) -$(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_SRCDIRS) +$(2)/%.o: $$(COMPONENT_PATH)/$(1)/%.S $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(COMPONENT_OBJDIRS) $$(summary) AS $$(patsubst $$(PWD)/%,%,$$(CURDIR))/$$@ - $$(CC) $$(CPPFLAGS) $$(DEBUG_FLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$< -o $$@ + $$(CC) $$(CPPFLAGS) $$(DEBUG_FLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I $(1) -c $$(abspath $$<) -o $$@ $(call AppendSourceToDependencies,$$<,$$@) # CWD is build dir, create the build subdirectory if it doesn't exist # -# (NB: Each .o file depends on all relative component build dirs $(COMPONENT_SRCDIRS), rather than just $(1), to work +# (NB: Each .o file depends on all relative component build dirs $(COMPONENT_OBJDIRS), including $(2), to work # around a behaviour make 3.81 where the first pattern (randomly) seems to be matched rather than the best fit. ie if # you have objects a/y.o and a/b/c.o then c.o can be matched with $(1)=a & %=b/c, meaning that subdir 'a/b' needs to be -# created but wouldn't be created if $(1)=a. Make 4.x doesn't have this problem, it seems to preferentially -# choose the better match ie $(1)=a/b and %=c ) +# created but wouldn't be created if $(2)=a. Make 4.x doesn't have this problem, it seems to preferentially +# choose the better match ie $(2)=a/b and %=c ) # -$(1): - mkdir -p $(1) +# Note: This may cause some issues for out-of-tree source files and make 3.81 :/ +# +$(2): + mkdir -p $(2) endef # Generate all the compile target patterns -$(foreach srcdir,$(COMPONENT_SRCDIRS), $(eval $(call GenerateCompileTargets,$(srcdir)))) +$(foreach srcdir,$(COMPONENT_SRCDIRS), $(eval $(call GenerateCompileTargets,$(srcdir),$(call stripLeadingParentDirs,$(srcdir))))) ## Support for embedding binary files into the ELF as symbols