CFG_DATA_FILES := $(wildcard ../src/config/cfg_file*.csv)
CFG_DATA_MEM_FILES := $(addprefix bin/,$(notdir $(CFG_DATA_FILES:.csv=.mem)))
CFG_DATA_BIN_FILES := $(addprefix bin/,$(notdir $(CFG_DATA_MEM_FILES:.mem=.bin)))
COMBINED_BIN_FILES := $(subst cfg_file-,fw_,$(CFG_DATA_BIN_FILES))
COMBINED_BIN_FILES := $(subst .bin,_combined.bin,$(COMBINED_BIN_FILES))
ifdef CUSTOM_CONFIG
rom: build_images create_custom_binaries
else
rom: build_images create_binaries
endif
chk_custom_cfg:
ifdef CUSTOM_CONFIG
export CUSTOM_CONFIG
$(eval CUST_CFG_DATA_FILES=$(CUSTOM_CONFIG))
export CUST_CFG_DATA_FILES
$(eval CUST_CFG_DATA_MEM_FILES=$(addprefix bin/,$(notdir $(CUST_CFG_DATA_FILES:.csv=.mem))))
export CUST_CFG_DATA_MEM_FILES
$(eval CUST_CFG_DATA_BIN_FILES=$(addprefix bin/,$(notdir $(CUST_CFG_DATA_MEM_FILES:.mem=.bin))))
export CUST_CFG_DATA_BIN_FILES
$(eval CUST_COMBINED_BIN_FILES=$(subst .bin,_combined.bin,$(CUST_CFG_DATA_BIN_FILES)))
export CUST_COMBINED_BIN_FILES
#echo existing cfg files $(CUST_CFG_DATA_FILES)
#echo existing mem files $(CUST_CFG_DATA_MEM_FILES)
#echo existing bin files $(CUST_CFG_DATA_BIN_FILES)
#echo existing combined files $(CUST_COMBINED_BIN_FILES)
endif
build_images: copy_ops_imgs
create_binaries: config $(COMBINED_BIN_FILES)
create_custom_binaries: chk_custom_cfg cust_config
#echo custom config bin files $(CUST_CFG_DATA_BIN_FILES)
config: boot_partn_map_cfg $(CFG_DATA_BIN_FILES)
#echo Removing temporary files
#(cd bin; rm -rf *.mem)
cust_config: boot_partn_map_cfg $(CUST_CFG_DATA_BIN_FILES)
#echo Removing temporary files
#(cd bin; rm -rf *.mem)
$(CFG_DATA_BIN_FILES): $(CFG_DATA_FILES)
#echo Generating config data image $(subst /bin,,$#)
$(CUST_CFG_DATA_BIN_FILES):$(CUST_CFG_DATA_FILES)
#echo Generating config data image $(subst /bin,,$#)
In the above make file :
calling "make CUSTOM_CONFIG=../src/config/custom.config rom" expect $(CUST_CFG_DATA_BIN_FILES) build for ../src/config/custom.config in target cust_config , but I see the environment variable update properly but the target cust_config will not build $(CUST_CFG_DATA_BIN_FILES).
Am I missing anything here, My goal is build different binaries based on the input CUSTOM_CONFIG
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 am trying to build a dummy C project using GNU Make. I use the following rules to build the object files from the c files and the output from the object files :
AT := #
#Initial tools to get the absolute paths.
TOOLSDIR := ./tools/bin
SHELL := $(TOOLSDIR)/sh
CYGPATH := $(TOOLSDIR)/cygpath
# Defining used tools
TOOLSDIR := $(shell $(CYGPATH) -am "$(TOOLSDIR)")
SCRIPTDIR := $(shell $(CYGPATH) -am "$(SCRIPTDIR)")
LIBDIR := $(shell $(CYGPATH) -am "$(LIBDIR)")
#Defining Env Variable responsible for Removing non-ansi characters in error output
LC_ALL=C
SHELL := $(shell $(CYGPATH) -am "$(SHELL)")
CYGPATH := $(shell $(CYGPATH) -am "$(CYGPATH)")
TEST := $(shell $(CYGPATH) -am "$(TOOLSDIR)/test")
RM := $(shell $(CYGPATH) -am "$(TOOLSDIR)/rm") -f
PERL := $(shell $(CYGPATH) -am "$(TOOLSDIR)/perl")
FIND := $(shell $(CYGPATH) -am "$(TOOLSDIR)/find")
MKDIR := $(shell $(CYGPATH) -am "$(TOOLSDIR)/mkdir")
PERL5LIB := $(LIBDIR)/perl5/site_perl/5.14/x86_64-cygwin-threads;$(LIBDIR)/perl5/site_perl/5.14;$(LIBDIR)/perl5/5.14/x86_64-cygwin-threads;$(LIBDIR)/perl5/5.14
# Defining perl script to convert dependencies genereted by the compiler to unix path
FIXDEPS_SCRIPT := "$(SCRIPTDIR)/fixdeps.pl"
ZAPEXEC_SCRIPT := "$(SCRIPTDIR)/ZAP_Command.pl"
DEPFIX := $(PERL) $(FIXDEPS_SCRIPT)
ZAPEXE := $(PERL) $(ZAPEXEC_SCRIPT)
CREATE_IAR_PROJ := $(PERL) $(IARWKSP_SCRIPT)
COMP_DIR :=C:\ghs\comp_201355
OBJDIR :=.
CC := "$(COMP_DIR)/ccrh850.exe"
AS := "$(COMP_DIR)/ccrh850.exe"
LD := "$(COMP_DIR)/ccrh580.exe"
GSREC := "$(COMP_DIR)/gsrec.exe"
GMEM := "$(COMP_DIR)/gmemfile.exe"
CEXT :=c
CCEXT :=C
ASMEXTC := S
ASMEXTS := s
ASMEXT := 850
ASMEXT_DEFAULT := asm
DBGEXT := dla
DBGEXT_DEFAULT := dnm
OBJEXT := o
EXEEXT := elf
LSTEXT := lst
DEPEXT := dd
INCOPT := -I
EXEMAP := ./exe/PROJECT_NAME.map
CFLAGS :=-c -G -Onone -no_callt -sda=all -large_sda -reserve_r2 -Wundef --short_enum -dual_debug \
-delete -preprocess_assembly_files --no_wrap_diagnostics -registermode=32 -keeptempfiles -prepare_dispose -ansi \
-full_debug_info -noobj -Wimplicit-int -Wshadow -Wtrigraphs -inline_prologue -DOS_MEMMAP=0 -DOS_MULTICORE=OS_SINGLE \
-DOS_USE_CLZ_QUEUE_ALGORITHM=1 -DOS_DEVELOPMENT_SANITY_CHECKS=0 -DOS_KERNEL_TYPE=OS_FUNCTION_CALL -DOS_USE_TRACE=0 -MD \
-DAUTOSAR_USED -DRENESAS -DF1K -DR7F701583xAFP --long_long -cpu=rh850 -DTS_ARCH_FAMILY=TS_RH850 \
-DTS_ARCH_DERIVATE=TS_RH850F1L -DRH850F1L=1 -DOS_CPU=OS_RH850F1L -DOS_TOOL=OS_ghs -DOS_ARCH=OS_RH850
VPATH :=./ ./obj ./src ./exe
INCLUDES :=-I"./" -I"./obj" -I"./src" -I"./exe"
OBJECTS :=./obj/main.o
.PHONY: all release debug
EXEC := ./exe/PROJECT_NAME.hex
EXEOUT := ./exe/PROJECT_NAME.out
all: debug release
release: $(EXEC)
debug: release
$(EXEC): $(EXEOUT)
#echo '************************************'
#echo 'Using GSREC to Convert .out to .hex'
$(AT)$(GSREC) -o$(EXEC) $(EXEOUT)
#echo 'Generation Done'
#echo '************************************'
$(EXEOUT): $(OBJECTS)
#echo '************************************'
#echo 'Building .out file'
#echo $(EXEOUT)
$(AT)$(CC) $(LDFLAGS) -o $(EXEOUT) $(OBJECTS)
#echo '************************************'
$(OBJDIR)/%.$(OBJEXT): %.$(CEXT)
#echo 'Compiling: $<'
$(AT)$(CC) $(CFLAGS) $(INCLUDES) -filetype.c $(shell $(CYGPATH) -am "$<") -o $#
The output when I execute the target all is as follows :
make: *** No rule to make target 'obj/main.o', needed by 'exe/PROJECT_NAME.out'. Stop.
The main.c source file has the following code :
#include <stdio.h>
#include <stdlib.h>
#include "alpha.c"
void second(void);
int main()
{
printf("Second module, I send you greetings!n");
second();
return 0;
}
The alpha.c source file has the following code :
#include <stdio.h>
void second(void)
{
puts("Glad to be here!");
}
Where $(OBJECTS) is the relative path of all the object files that are supposed to be generated and $(EXEC) and $(EXEOUT) are the outputs. The VPATH contains relative paths. All the needed prerequisites (.c and.h files) can be found among the paths in VPATH and in INCLUDES in the compilation command. That is the exact code I use to build this dummy project which contains only two .c files main.c and alpha.c and main.c uses alpha.c. When the source files are in the same folder as the makefile this dummy project builds, but when I put the source files in the src folder and create a obj folder for the object files to be generated in and an exe folder for the final output to be generated in previously mentioned error appears. What could be the reason for the previously mentioned error?
#Beta is right that it's generally a bad idea to dump a huge makefile into StackOverflow and ask someone to fix it. You should instead try to reduce the problem as much as possible.
However in this case, your problem is here:
OBJDIR :=.
OBJECTS :=./obj/main.o
$(EXEOUT): $(OBJECTS)
...
$(OBJDIR)/%.$(OBJEXT): %.$(CEXT)
...
So after all the variables have been expanded, you get these rules:
./exe/PROJECT_NAME.out: ./obj/main.o
...
./%.o: %.c
...
Well, when make tries to match the pattern ./%.o with the target to be built ./obj/main.o, the stem % will match obj/main. Then it will try to find %.c which resolves to obj/main.c, which doesn't exist.
You should be using the OBJDIR variable in your OBJECTS variable assignment, like:
OBJECTS :=$(OBJDIR)/main.o
then it will work.
Looking for ways to assign a variable in a Makefile based on the existence of a directory.
Eg: (pseudo code)
if dir "src/$(project)" exists
SOURCE_DIR := src/$(project)
else
SOURCE_DIR := src/default
test.o: $SOURCE_DIR/test.c
gcc -c -o $# $<
What's the best way to achieve the above
As your source directory will contain files and a non-existing directory will not, you can utilize the GNU make internal function $(wildcard):
project := test
# returns all entries under src/$(project) directory or empty string
ifneq ($(wildcard src/$(project)/*),)
SOURCE_DIR := src/$(project)
else
SOURCE_DIR := src/default
endif
.PHONY: all
all:
#echo $(SOURCE_DIR)
Test run
$ ls src/test/
a.c
$ make
src/test
$ rm -rf src/test
$ make
src/default
BONUS: it might be more readable to rewrite the conditional like this:
SOURCE_DIR := src/$(project)
ifeq ($(wildcard $(SOURCE_DIR)/*),)
# fall back to default directory
SOURCE_DIR := src/default
endif
UPDATE 2: if you don't want to rely on the existence of any files in the directory, you can also test the directory name directly. A directory always has an entry ., because it points to itself:
SOURCE_DIR := src/$(project)
ifeq ($(wildcard $(SOURCE_DIR)/.),)
# fall back to default directory
SOURCE_DIR := src/default
endif
UPDATE 3: adding a check that $(project) is set:
SOURCE_DIR := src/$(project)
ifeq ($(strip $(project)),)
# fall back to default directory
SOURCE_DIR := src/default
else ifeq ($(wildcard $(SOURCE_DIR)/.),)
# fall back to default directory
SOURCE_DIR := src/default
endif
or if you prefer makefile Golfing (thanks #MadScientist for the suggestion)
SOURCE_DIR := $(or $(and $(project),$(wildcard src/$(project)/.)),src/default)
$(and) result
if $(project) is an empty string: empty string
if src/$(project) is not a directory: empty string
otherwise: src/$(project)/., which is equivalent to src/$(project)
$(or) result
if $(and) returns empty string: src/default
otherwise: the string returned by $(and)
CAVEAT: the above listed tests will fail if $(project) contains white space.
Try this.
SOURCE_DIR := src/$(shell test -d src/"$(project)" && echo "$(project)" || echo default)
I have, in the main repository some subdirectories called assignment_1, assignment_2, ..., assignment_n.
I'm tring to write a Makefile that compiles the all TeX files inside those subdirectories.
This is what I have so far, but it doesn't work:
.PHONY: papers clean
PUBLISH_DIR := publish
TEX_DIR := .tex
SRC_DIR := assignment_$(wildcard *)
SRC_FILES := $(wildcard $(SRC_DIR)/*.tex)
CC := xelatex
FLAGS := -shell-escape -output-directory=$(TEX_DIR)
all: $(patsubst $(SRC_DIR)/%.tex, $(PUBLISH_DIR)/%.pdf, $(SRC_FILES))
$(PUBLISH_DIR)/%.pdf: $(SRC_DIR)/%.tex
mkdir -p $(TEX_DIR)
$(CC) $(FLAGS) $<
$(CC) $(FLAGS) $<
mkdir -p $(PUBLISH_DIR)
mv $(TEX_DIR)/*.pdf $(PUBLISH_DIR)/
clean:
rm -rf $(PUBLISH_DIR) $(TEX_DIR)
If I change this line
SRC_DIR := assignment_$(wildcard *)
with
SRC_DIR := assignment_1
it works beautifully but (obviously) only with the TeX file inside assignment_1.
Beside traversing the subdirectories, is there anything else I can improove in this Makefile?
I think you should modify your wildcard:
SRC_DIR := assignment_$(wildcard *)
to
SRC_DIR := $(wildcard assignment_*)
If $(wildcard *) expands to 1 2 3 then assignment_$(wildcard *) will expand to assignment_1 2 3 which is clearly not what you want.
Try this:
SRC_DIR := $(addprefix assignment_,$(wildcard *))
to add the assignment_ prefix to the start of each word.
I would like to apply the 'notdir'-function to a list of files I obtain from a wildcard match. While '$(notdir $(wildcard dir/*.tst))' works, I do not manage to first store the list in a variable ('FILES' in the Makefile below) that then is processed by $(notdir ...). Using the variable directly ('$(notdir $(FILES))') results in the wildcard being returned, using value ('$(notdir $(value $(FILES)))') yields an empty result.
.PHONY: show
FILES := dir/*.tst
FILES2 := dir/a.tst dir/b.tst
#NAMES := $(notdir $(FILES))
NAMES1 := $(notdir $(value $(FILES)))
NAMES2 := $(notdir $(FILES2))
NAMES3 := $(notdir $(wildcard dir/*.tst))
show:
#echo "FILES: " $(FILES)
#echo "NAMES1: " $(NAMES1)
#echo "NAMES2: " $(NAMES2)
#echo "NAMES3: " $(NAMES3)
I also tried $(notdir $(eval $$(FILES))), but this results in a "missing separator" error.
What am I missing here? I'd have expected that value would do the job...
Try the following:
FILES := $(wildcard dir/*.tst)
NAMES := $(notdir ${FILES})