Background, I suspect XY problem
I have simpler C modules in a directory. I want to write unit tests for these in a sub-directory test/. These unit tests are no more than C programs linking to the module under test, one directory above. I want a Makefile that defines several build targets and lets me build and run the test executables in one step, or separately.
My attempted solution
I've attempted the following:
CC = gcc
CFLAGS = -ggdb -Wall -Wextra -Werror -O3 -std=c99
PARAM_LIST_TARGET = parameter_list_test
PARAM_LIST_SOURCE_FILES = \
../parameter_list.c \
parameter_list_test.c
PARAM_LIST_OBJECT_FILES := $(addsuffix .o,$(basename $(PARAM_LIST_SOURCE_FILES)))
TARGETS = $(PARAM_LIST_TARGET)
all: $(TARGETS)
$(%_TARGET): $(%_OBJECT_FILES)
$(CC) $(CFLAGS) $^ -o $#
.c.o:
$(CC) -c $< -o $# $(CFLAGS)
clean:
$(RM) *.o $(TARGETS)
test: all
#for t in $(TARGETS) ; do ./$$t ; done
This doesn't work, and it's because of the $(%_TARGET): row. Not surprising, I didn't expect it to work, but I hope this illustrates what I'm trying to achieve.
I want to create more chunks of the form _TARGET, _SOURCE_FILES, and _OBJECT_FILES, to test other modules besides PARAM_LIST, for example:
PARAM_LIST_TARGET = parameter_list_test
PARAM_LIST_SOURCE_FILES = \
../parameter_list.c \
parameter_list_test.c
PARAM_LIST_OBJECT_FILES := $(addsuffix .o,$(basename $(PARAM_LIST_SOURCE_FILES)))
OTHER_MODULE_TARGET = other_module_test
OTHER_MODULE_SOURCE_FILES = \
../other_module.c \
other_module_test.c
OTHER_MODULE_OBJECT_FILES := $(addsuffix .o,$(basename $(OTHER_MODULE_SOURCE_FILES)))
I understand that % works on filenames, so attempting to use it on variables fails:
$(%_TARGET): $(%_OBJECT_FILES)
$(CC) $(CFLAGS) $^ -o $#
How can I write a rule that matches the Makefile variables _TARGET to their associated _OBJECT_FILES, without creating one per test target?
Or more importantly, how should I do it totally differently?
Edit: I've seen this, however it seems it's only working with a single source file per executable.
You can always access make variables by constructing their names:
MY_VAR := "my var"
HIS_VAR := "his var"
HER_VAR := "her var"
CATS_VAR := "cats var"
DOGS_VAR := "dogs var"
ALL_PERSONS := MY HIS HER CATS DOGS
ALL_VARS := $(foreach p,$(ALL_PERSONS),$($(p)_VAR))
$(info $(ALL_VARS))
Output:
$ make
"my var" "his var" "her var" "cats var" "dogs var"
Defining the dependencies separately seems to work, thanks to this answer:
TARGETS = $(PARAM_LIST_TARGET) $(OTHER_MODULE_TARGET)
all: $(TARGETS)
$(PARAM_LIST_TARGET): $(PARAM_LIST_OBJECT_FILES)
$(OTHER_MODULE_TARGET): $(OTHER_MODULE_OBJECT_FILES)
$(TARGETS):
$(CC) $(CFLAGS) $^ -o $#
This eliminates the need for a duplicate rule (one per target). Still, the definition of dependencies for each target looks like duplicates, a pattern match for these would be nice.
More than that, the OBJECT_FILES variable becomes unnecessary. This works:
PARAM_LIST_TARGET = parameter_list_test
PARAM_LIST_SOURCE_FILES = \
../parameter_list.c \
parameter_list_test.c
$(PARAM_LIST_TARGET): $(addsuffix .o,$(basename $(PARAM_LIST_SOURCE_FILES))) # The dependencies directly
It would still feel nice to have this last row as one rule for all targets. Something like "for all variables ending with TARGET, build a dependency to the content of the variable with the same name, but ending with SOURCE_FILES instead".
Related
Have two files, namely pyproject.toml and poetry.lock which is located in a folder called dump. I want to move those files to 2 directories for when running tests.
Today I do thise
PROJECT_DIR := $(realpath $(CURDIR))
BUILD_DUMP_DIR := $(PROJECT_DIR)/dump
DESTINATION_DIRS := unit system endtoend
PY_SOURCES = $(patsubst %,$(BUILD_DUMP_DIR)/%, pyproject.toml)
POETRY_SOURCES = $(patsubst %,$(BUILD_DUMP_DIR)/%, poetry.lock)
PY_PROJECT = $(foreach dir, $(DESTINATION_DIRS), $(patsubst %, $(BUILD_DUMP_DIR)/tests/$(dir)/%, pyproject.toml))
POETRY_PROJECT = $(foreach dir, $(DESTINATION_DIRS), $(patsubst %, $(BUILD_DUMP_DIR)/tests/$(dir)/%, poetry.lock))
$(PY_PROJECT): $(PY_SOURCES)
#echo "=> Moving $< to $#"
#cp $< $#
$(POETRY_PROJECT): $(POETRY_SOURCES)
#echo "=> Moving $< to $#"
#cp $< $#
copy-dump: $(PY_PROJECT) $(POETRY_PROJECT)
so running make copy-dump will move those files to the specified directory. Realize there must be nicer MakeFile command to do this. Thanks for all input
Not sure I understood all details but if you use GNU make and you want to copy (not move) your 2 files to 3 different locations each, the following is a bit simpler:
PROJECT_DIR := $(realpath $(CURDIR))
BUILD_DUMP_DIR := $(PROJECT_DIR)/dump
DESTINATION_DIRS := unit system endtoend
PY_SOURCES = $(BUILD_DUMP_DIR)/pyproject.toml
POETRY_SOURCES = $(BUILD_DUMP_DIR)/poetry.lock
PY_PROJECT = $(patsubst %,$(BUILD_DUMP_DIR)/tests/%/pyproject.toml,$(DESTINATION_DIRS))
POETRY_PROJECT = $(patsubst %,$(BUILD_DUMP_DIR)/tests/%/poetry.lock,$(DESTINATION_DIRS))
.PHONY: copy-dump
copy-dump: $(PY_PROJECT) $(POETRY_PROJECT)
.SECONDEXPANSION:
$(PY_PROJECT) $(POETRY_PROJECT): $(BUILD_DUMP_DIR)/$$(notdir $$#)
#echo "=> Moving $< to $#"
#cp $< $#
See the GNU make documentation for the details about secondary expansion.
I'm using GNU Make and attempting to design Makefiles using non-recursive approach. The issue I have - there doesn't seem to be a way to limit the scope of variables in different Makefiles.
For example, if I have two Makefiles for modules libA and libB
libA Makefile.inc:
src_dir := libA/src
inc_dir := libA/inc
libB Makefile.inc:
src_dir := libB/src
inc_dir := libB/inc
Then when I include the above Makefiles into a master Makefile
include libA/Makefile.inc
include libB/Makefile.inc
Values in variables src_dir and inc_dir are overwritten by the very last Makefile that was included. OK this is probably expected since variables are global in scope here, and this messes up build commands that use those variables, i.e. build command for libA finds variable values for libB.
A way around it is to create unique variables for each Makefile
libA Makefile.inc:
src_dir_libA := libA/src
inc_dir_libA := libA/inc
libB Makefile.inc:
src_dir_libB := libB/src
inc_dir_libB := libB/inc
This solves the issue, but it's a bit awkward to use, since each variable has to be renamed. Does anyone know if there is a better way to solve this, e.g. if GNU Make has some notion of scope or namespace? I've looked at documentation, but can't seem to find anything of that sort. There are target-specific variables, but they appear to have nasty side-effects.
OK, just to be very specific, below is an example Makefile
dep_all :=
all:
# Begin Makefile.inc for project1
# ------------------------------------------------------------------------------
$(foreach var,$(filter local_%,$(.VARIABLES)),$(eval $(var) := ))
local_src_dir := project1/src
local_obj_dir := project1/obj
local_src := $(local_src_dir)/fileA.c $(local_src_dir)/fileB.c
local_obj := $(patsubst $(local_src_dir)/%.c,$(local_obj_dir)/%.o,$(local_src))
dep_all += $(local_src)
dep_all += $(local_obj)
$(info local_obj="$(local_obj)")
$(local_obj): $(local_obj_dir)/%.o: $(local_src_dir)/%.c
gcc -L$(local_obj_dir) -c -o $# $<
# ------------------------------------------------------------------------------
# End Makefile.inc for project1
# Begin Makefile.inc for project2
# ------------------------------------------------------------------------------
$(foreach var,$(filter local_%,$(.VARIABLES)),$(eval $(var) := ))
local_src_dir := project2/src
local_obj_dir := project2/obj
local_src := $(local_src_dir)/fileX.c $(local_src_dir)/fileY.c
local_obj := $(patsubst $(local_src_dir)/%.c,$(local_obj_dir)/%.o,$(local_src))
dep_all += $(local_src)
dep_all += $(local_obj)
$(info local_obj="$(local_obj)")
$(local_obj): $(local_obj_dir)/%.o: $(local_src_dir)/%.c
gcc -L$(local_obj_dir) -c -o $# $<
# ------------------------------------------------------------------------------
# End Makefile.inc for project2
$(info dep_all="$(dep_all)")
.PHONY: all
all: $(dep_all)
.PHONY: clean
clean:
rm -f project1/obj/* project2/obj/*
If I run it then the -L<object_path> option passed to gcc contains value from the last included Makefile, i.e. when building project1, it runs gcc with -Lproject2/obj, which is not the right object path for this project. This is the problem I'm trying to solve.
mkdir -p project1/{src,obj} project2/{src,obj}
touch project1/src/{fileA.c,fileB.c} project2/src/{fileX.c,fileY.c}
$ make
local_obj="project1/obj/fileA.o project1/obj/fileB.o"
local_obj="project2/obj/fileX.o project2/obj/fileY.o"
dep_all=" project1/src/fileA.c project1/src/fileB.c project1/obj/fileA.o project1/obj/fileB.o project2/src/fileX.c project2/src/fileY.c project2/obj/fileX.o project2/obj/fileY.o"
gcc -Lproject2/obj -c -o project1/obj/fileA.o project1/src/fileA.c
gcc -Lproject2/obj -c -o project1/obj/fileB.o project1/src/fileB.c
gcc -Lproject2/obj -c -o project2/obj/fileX.o project2/src/fileX.c
gcc -Lproject2/obj -c -o project2/obj/fileY.o project2/src/fileY.c
The solution is to name all your variables local to a specific file with some prefix.
For example, I use this_ prefix.
Then, in the beginning of each submakefile those variales which have this_ prefix can be cleared as follows:
$(foreach var,$(filter this_%,$(.VARIABLES)),$(eval $(var) := ))
PS. I use this approach in my implementation of non-recursive makefiles, clearing the variables described in the WIKI here: https://github.com/cppfw/prorab
I think I've just figured out a solution. I was reading "The GNU Make Book" and it states a side effect of target specific variables
Target-specific variables apply not just to a target, but also to all
that target’s prerequisites, as well as all their prerequisites, and
so on. A target-specific variable’s scope is the entire tree of
targets, starting from the target for which the variable was defined.
This is not the behaviour I want, however starting with GNU Make 3.82 there is support for private target specific variables
A target-specific variable is normally defined for a target and all
its prerequisites. But if the target-specific variable is prefixed
with the keyword private, it is defined only for that target, not its
prerequisites.
So the following Makefile seems to work correctly for those private variables
dep_all :=
all:
# Begin Makefile.inc for project1
# ------------------------------------------------------------------------------
inc_dir := project1/inc
src_dir := project1/src
obj_dir := project1/obj
src := $(src_dir)/fileA.c $(src_dir)/fileB.c
obj := $(patsubst $(src_dir)/%.c,$(obj_dir)/%.o,$(src))
# These flags will be overwritten by another Makefile
CFLAGS := -I$(inc_dir)
# These flags will be private and not be overwritten by another Makefile
CFLAGS_priv := -I$(inc_dir) -L$(obj_dir)
dep_all += $(src)
dep_all += $(obj)
# Private target specific variables
$(obj): private CFLAGS_priv:=$(CFLAGS_priv)
$(obj): $(obj_dir)/%.o: $(src_dir)/%.c
gcc $(CFLAGS) $(CFLAGS_priv) -c -o $# $<
# ------------------------------------------------------------------------------
# End Makefile.inc for project1
# Begin Makefile.inc for project2
# ------------------------------------------------------------------------------
inc_dir := project2/inc
src_dir := project2/src
obj_dir := project2/obj
src := $(src_dir)/fileX.c $(src_dir)/fileY.c
obj := $(patsubst $(src_dir)/%.c,$(obj_dir)/%.o,$(src))
# These flags will be overwritten by another Makefile
CFLAGS := -I$(inc_dir)
# These flags will be private and not be overwritten by another Makefile
CFLAGS_priv := -I$(inc_dir) -L$(obj_dir)
dep_all += $(src)
dep_all += $(obj)
# Private target specific variables
$(obj): private CFLAGS_priv:=$(CFLAGS_priv)
$(obj): $(obj_dir)/%.o: $(src_dir)/%.c
gcc $(CFLAGS) $(CFLAGS_priv) -c -o $# $<
# ------------------------------------------------------------------------------
# End Makefile.inc for project2
.PHONY: all
all: $(dep_all)
.PHONY: clean
clean:
rm -f project1/obj/* project2/obj/*
The output is what I wanted, since now for each project I can define private CFLAGS_priv variable that sets -I<dir>, -L<dir> paths and it won't be overwritten by other Makefiles.
$ make
gcc -Iproject2/inc -Iproject1/inc -Lproject1/obj -c -o project1/obj/fileA.o project1/src/fileA.c
gcc -Iproject2/inc -Iproject1/inc -Lproject1/obj -c -o project1/obj/fileB.o project1/src/fileB.c
gcc -Iproject2/inc -Iproject2/inc -Lproject2/obj -c -o project2/obj/fileX.o project2/src/fileX.c
gcc -Iproject2/inc -Iproject2/inc -Lproject2/obj -c -o project2/obj/fileY.o project2/src/fileY.c
I'm hoping this will resolve all issues I had and I don't have to use recursive make with it's various associated pitfalls.
I have the following makefile in the root of the project:
Makefile
# Board version
# Available: 3
PI ?= 3
# Kernel binaries
ifeq ($(PI), 3)
KERNEL_IMG := kernel8.img
else ifeq ($(PI), 2)
KERNEL_IMG := kernel7.img
else ifeq ($(PI), 1)
KERNEL_IMG := kernel.img
else
$(error Unsupported Raspberry Pi version)
endif
KERNEL_ELF := $(patsubst %.img,%.elf,$(KERNEL_IMG))
# Directories/paths
BUILD_DIR := build
# Toolchain
TOOLCHAIN ?= aarch64-elf
OBJCOPY := $(TOOLCHAIN)-objcopy
LD := $(TOOLCHAIN)-ld
CC := $(TOOLCHAIN)-gcc
# Misc
LINKER_SCRIPT := linker.ld
# Flags
LDFLAGS := -T $(LINKER_SCRIPT)
ASFLAGS :=
CFLAGS :=
# Source files
C_SRC := $(wildcard *.c)
ASM_SRC := $(wildcard *.S)
# Include
include pi/$(PI)/mod.mk
# Object files
OBJECTS := $(patsubst %,$(BUILD_DIR)/%.o,$(C_SRC))
OBJECTS += $(patsubst %,$(BUILD_DIR)/%.o,$(ASM_SRC))
# Targets
.PHONY: all builddirs clean
all: $(BUILD_DIR)/$(KERNEL_IMG)
$(BUILD_DIR)/$(KERNEL_IMG): $(BUILD_DIR)/$(KERNEL_ELF)
$(OBJCOPY) $< -O binary $#
$(BUILD_DIR)/$(KERNEL_ELF): $(LINKER_SCRIPT) $(OBJECTS)
$(LD) $(OBJECTS) $(LDFLAGS) -o $#
$(OBJECTS): | builddirs
builddirs: $(BUILD_DIR)/pi/$(PI)
$(BUILD_DIR)/pi/$(PI):
mkdir -p $#
$(BUILD_DIR)/%.S.o: %.S
$(CC) -c $< $(ASFLAGS) -o $#
$(BUILD_DIR)/%.c.o: %.c
$(CC) -c $< $(CFLAGS) -o $#
clean:
$(RM) -r $(BUILD_DIR)
It includes pi/3/mod.mk
C_SRC +=
ASM_SRC += pi/3/start.S
$(BUILD_DIR)/pi/3/start.S.o: pi/3/start.S pi/3/include/cpu/sysregs.h
$(CC) -c $< $(ASFLAGS) -o $#
Now here's the problem: whenever I run 'make' in the root of a project, '$(BUILD_DIR)/pi/3/start.S.o' rule invokes, instead of 'all'. If I move 'include pi/$(PI)/mod.mk' to the very bottom of the root makefile, and replace 'C_SRC' and 'ASM_SRC' variables in 'pi/3/mod.mk' with 'OBJECTS += $(BUILD_DIR)/pi/3/start.S.o' and invoke 'make', this rule isn't even invoked, so I get an error that make doesn't know how to build start.S.o.
What am I doing wrong and what is the best way to handle this?
Make's default goal is the first target in your Makefile. In your case the first target is the one defined in the included Makefile: $(BUILD_DIR)/pi/3/start.S.o. Either invoke make all or move the all rule in your Makefile such that it becomes the first one, or tell make that the default goal is all:
.DEFAULT_GOAL := all
(see GNU make manual).
Have problem in dynamically "create" target name with .SECONDEXPANSION:
Small Makefile to reproduce problem:
CONFIGS = test1 test2 test3
.SECONDEXPANSION:
all: $(CONFIGS)
OBJECTS=$$(CFG_NAME)_OBJECTS
$(CONFIGS) : CFG_NAME=$#
$(CONFIGS) : $(OBJECTS)
#echo $(CFG_NAME) $# from $^
$(OBJECTS):
#echo OBJECTS $# from $^
#echo DO IT
It says: "No rule to make target 'test1_OBJECTS'.
How can I solve this problem?
EDIT: CHANGE OF THE ANSWER
Thank you much for the answer. It was the simple variant for my task.
So I try to answer in another way.
CONFIGS = test1 test2 test3
PLATFORMS = x86 ppc arm
#will be test1x86 test2x86 ... test1ppc ... test3arm,
#so it is long way to enumarate all variants
VARIANTS = $(foreach c, $(CONFIGS), $(foreach p, $(PLATFORMS), $(c)$(p)))
#C FILE LIST
CFILES:=$(shell /bin/find -name "*.c")
.SECONDEXPANSION:
all: $(VARIANTS)
#More Comlex Rule
#Want to corresponding objects be in bins/test1x86/
OBJECTS:=$(CFILES:%.c=bins/$$(CFGNAME)%.o)
$(CONFIGS) : CFG_NAME=$#
$(CONFIGS) : $(OBJECTS)
#echo $(CFG_NAME) $# from $^
#More complex prerequisites
#I understand that $$(CFGNAME) will be resolve incorrect.
#For each *.c file in subdir I would have object in corresponding path.
#For example, '1/2/3/test.c' will use for generate
#object file 'bins/test1x86/1/2/3/test.o',
#when I call 'make testx86' or 'make all' (it will build all VARIANTS),
#in 'bins/test1x86/1/2/3/'.
#So what have I do?
$(OBJECTS): bins/$$(CFGNAME)_OBJECTS/%o : %.c
#echo OBJECTS $# from $^
#echo DO IT
So, I would like to avoid recursive make calls. Can you help me?
Thank you.
You have a rule for $(OBJECTS), but that target expands to $(CFG_NAME)_OBJECTS, which is not expanded again (ever), so it can't match anything. Try this instead:
test1_OBJECTS test2_OBJECTS test3_OBJECTS:
#echo OBJECTS $# from $^
#echo DO IT
Or better:
OBJECT_SETS = $(addsuffix _OBJECTS, $(CONFIGS))
$(OBJECT_SETS):
#echo OBJECTS $# from $^
#echo DO IT
(And I'm sure you realize your example doesn't really need SECONDEXPANSION at all.)
EDIT:
That should be a separate question, but I'll try to answer it here. (And please use punctuation in the comments in your makefile; they are very difficult to understand.)
There is more than one solution to your problem. Here is one:
vpath %.c $(dir $(CFILES))
CFILES := $(notdir $(CFILES))
I've gotcha it.
CONFIGS = test1 test2 test3
PLATFORMS = p1 p2
#Will be testp1 test1p2 .. test3p2
VARIANTS = $(foreach c, $(CONFIGS), $(foreach p, $(PLATFORMS), $(c)$(p)))
.SECONDEXPANSION:
#.c files list in all subfolders
cfiles = $(shell /bin/find -name "*.c")
#objects for these .c files for custom VARIANT
objects = $(patsubst %.c,%.o,$(addprefix bins/$1/,$(cfiles)))
#Get .c source for object (e.g. bins/test1p1/tests/main_test.o => tests/main_test.c)
get_src=$(shell echo $1 | sed 's/[^\/]*\/[^\/]*\/\(.*\)/\1.c/')
#Build All Variants
all: $(VARIANTS)
#Build objects. Target list contains all objects for all variants.
#Prerequisites get .c sources from the pattern rule for targets
$(foreach v, $(VARIANTS), $(call objects,$(v))) : %.o : $$(call get_src,$$*)
#echo OBJECTS $# FROM $^
#Variants rule, depends on objects
$(VARIANTS): $(call objects,$$#)
#echo $# from $^
Thank you, Beta. You only have tried. :)
Maybe anyone have style or efficiency suggestions.
I have a big chunk of my makefile (~50 lines) that needs to be copy-pasted 5 times for different case (the different libraries used). Is it possible to create a function in a makefile and just call that function instead of copy-pasting?
This is an example of what I've tried. Basically this tries to find the right path for an installed library.
define Flags_template
$(1)_include_home := $(HOME)/usr/include
$(1)_include_home_name := $(HOME)/usr/include/$(1)
ifneq ($$(wildcard $($(1)_include_home)/$(2)),)
$(1)_Include := $$($(1)_include_home)
else
ifneq ($$(wildcard $($(1)_include_home_name)/$(2)),)
$(1)_Include := $$($(1)_include_home_name)
endif
endif
CFLAGS += -I$$($(1)_Include)
endef
$(eval $(call Flags_template,stdcout,StdCout.hpp))
.PHONY: test
test:
# stdcout_include_home_name = $(stdcout_include_home_name)
# stdcout_Include = $(stdcout_Include)
# CFLAGS: $(CFLAGS)
Typing "make", I get this output:
# stdcout_include_home_name = /home/nicolas/usr/include/stdcout
# stdcout_Include =
# CFLAGS: -I
It's so close. But note the last "-I", I always get dupplicates, one fully expended, one empty...
I don't understant what needs to be eval'ed, escaped with two $, etc.
How can I achieve this?
Thank you very much.
Does §8.8 of the GNU Make (3.82) manual help?
[...] Although it might seem overly complex to use eval in this example,
rather than just writing out the rules, consider two things: first, the template definition (in
PROGRAM_template) could need to be much more complex than it is here; and second, you
might put the complex, “generic” part of this example into another makefile, then include
it in all the individual makefiles. Now your individual makefiles are quite straightforward.
PROGRAMS = server client
server_OBJS = server.o server_priv.o server_access.o
server_LIBS = priv protocol
client_OBJS = client.o client_api.o client_mem.o
client_LIBS = protocol
# Everything after this is generic
.PHONY: all
all: $(PROGRAMS)
define PROGRAM_template =
$(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%)
ALL_OBJS += $$($(1)_OBJS)
endef
$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))
$(PROGRAMS):
$(LINK.o) $^ $(LDLIBS) -o $#
clean:
rm -f $(ALL_OBJS) $(PROGRAMS)
This Works (For Me)
This is the output from the GNU makefile just below:
stdcout_include_home = /work4/jleffler/usr/include
stdcout_include_home_name = /work4/jleffler/usr/include/stdcout
stdcout_Include = /work4/jleffler/usr/include
CFLAGS: -I/work4/jleffler/include -I/work4/jleffler/usr/include
GNU Makefile
CFLAGS = -I${HOME}/include
define Flags_template
$(1)_include_home := $(HOME)/usr/include
$(1)_include_home_name := $(HOME)/usr/include/$(1)
ifneq ($$(wildcard $$($(1)_include_home)/$(2)),)
$(1)_Include := $$($(1)_include_home)
else
ifneq ($$(wildcard $$($(1)_include_home_name)/$(2)),)
$(1)_Include := $$($(1)_include_home_name)
else
$(1)_Include := Neither $$($(1)_include_home) nor $$($(1)_include_home_name) contains $2
endif
endif
CFLAGS += -I$$($(1)_Include)
endef
$(eval $(call Flags_template,stdcout,StdCout.hpp))
.PHONY: test
test:
#echo stdcout_include_home = $(stdcout_include_home)
#echo stdcout_include_home_name = $(stdcout_include_home_name)
#echo stdcout_Include = $(stdcout_Include)
#echo CFLAGS: $(CFLAGS)
The difference is in the wildcard invocations:
ifneq ($$(wildcard $($(1)_include_home)/$(2)),) # Fails
ifneq ($$(wildcard $$($(1)_include_home)/$(2)),) # Works
I have half an intuition about when double-dollars and when single-dollars are needed; I am not sure I can articulate the decision, though.