Why does my makefile call rm on dependencies after building? - makefile

When I run make -j tests, it makes the tests just fine but removes the dependencies afterwards. Why is it doing this and how can I solve it? I apologize for the complicated makefile. The relevant portions of the makefile are the Test sections.
Makefile:
# Build tools
CC = clang++ -g --std=gnu++11 -O3
LEX = flex
YACC = bison -d
# Includes
CC_HEADERS = `llvm-config-3.5 --cppflags`
CC_LIBRARIES = -lboost_program_options `llvm-config-3.5 --libs all --ldflags` -ltinfo -lpthread -lffi -ldl -lm -lz
# Created files
GENERATED_SOURCES = parser.cpp tokens.cpp
GENERATED_FILES = $(GENERATED_SOURCES)
EXEC = brainfuck.out
# Test cases
TESTS = $(wildcard ./tests/*.bf)
TESTS_IN = $(TESTS:.bf=.in)
TESTS_BUILD = $(TESTS:.bf=.build)
TESTS_EXPECTED = $(TESTS:.bf=.expected)
TESTS_ACTUAL = $(TESTS:.bf=.actual)
TESTS_DIFF = $(TESTS:.bf=.diff)
GENERATED_FILES += $(TESTS_BUILD) $(TESTS_EXPECTED) $(TESTS_ACTUAL) $(TESTS_DIFF)
# Generic config
SOURCES = $(filter-out $(GENERATED_SOURCES), $(wildcard *.cpp))
SOURCES += $(GENERATED_SOURCES)
OBJECTS = $(SOURCES:.cpp=.o)
# Main targets
target: $(EXEC)
all: target tests
# Generated source targets
tokens.cpp: tokens.l parser.hpp
$(LEX) -o $# $<
parser.hpp: parser.cpp
parser.cpp: parser.y
$(YACC) -o $# $<
# Test targets
tests: $(TESTS_DIFF)
#echo ""
#echo "#####################"
#echo "# Begin test output #"
#echo "#####################"
#$(foreach f,$^, echo "Test:" $(f:.diff=.bf); cat $(f); echo "";)
#echo "#####################"
#echo "# End test output #"
#echo "#####################"
#echo ""
tests/%.build: tests/%.bf $(EXEC)
./brainfuck.out $< -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o $#
tests/%.expected: tests/%.bf tests/%.in
-bf -c65535 $< < $(word 2,$^) > $#
tests/%.actual: tests/%.build tests/%.in
-$< < $(word 2,$^) > $#
tests/%.diff: tests/%.expected tests/%.actual
-diff $< $(word 2,$^) > $#
# Generic targets
clean:
rm -rf $(EXEC) $(OBJECTS) $(GENERATED_FILES) $(GENERATED_SOURCES:.cpp=.hpp)
$(EXEC): $(OBJECTS)
$(CC) -o $# ${OBJECTS} $(CC_LIBRARIES)
%.o: %.cpp parser.hpp
$(CC) $(CC_HEADERS) -c $< -o $#
Make output:
bf -c65535 tests/awib-0.4.bf < tests/awib-0.4.in > tests/awib-0.4.expected
./brainfuck.out tests/awib-0.4.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/awib-0.4.build
bf -c65535 tests/dbfi.bf < tests/dbfi.in > tests/dbfi.expected
./brainfuck.out tests/dbfi.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/dbfi.build
bf -c65535 tests/factor.bf < tests/factor.in > tests/factor.expected
./brainfuck.out tests/factor.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/factor.build
bf -c65535 tests/hanoi.bf < tests/hanoi.in > tests/hanoi.expected
./brainfuck.out tests/hanoi.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/hanoi.build
bf -c65535 tests/long.bf < tests/long.in > tests/long.expected
./brainfuck.out tests/long.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/long.build
bf -c65535 tests/mandelbrot.bf < tests/mandelbrot.in > tests/mandelbrot.expected
./brainfuck.out tests/mandelbrot.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/mandelbrot.build
bf -c65535 tests/prime.bf < tests/prime.in > tests/prime.expected
./brainfuck.out tests/prime.bf -p | llc-3.5 - -o - | gcc -O0 -x assembler - -o tests/prime.build
tests/dbfi.build < tests/dbfi.in > tests/dbfi.actual
tests/long.build < tests/long.in > tests/long.actual
tests/factor.build < tests/factor.in > tests/factor.actual
tests/prime.build < tests/prime.in > tests/prime.actual
tests/mandelbrot.build < tests/mandelbrot.in > tests/mandelbrot.actual
tests/hanoi.build < tests/hanoi.in > tests/hanoi.actual
tests/awib-0.4.build < tests/awib-0.4.in > tests/awib-0.4.actual
diff tests/factor.expected tests/factor.actual > tests/factor.diff
diff tests/awib-0.4.expected tests/awib-0.4.actual > tests/awib-0.4.diff
diff tests/mandelbrot.expected tests/mandelbrot.actual > tests/mandelbrot.diff
diff tests/hanoi.expected tests/hanoi.actual > tests/hanoi.diff
diff tests/long.expected tests/long.actual > tests/long.diff
diff tests/prime.expected tests/prime.actual > tests/prime.diff
diff tests/dbfi.expected tests/dbfi.actual > tests/dbfi.diff
#####################
# Begin test output #
#####################
Test: tests/awib-0.4.bf
Test: tests/dbfi.bf
Test: tests/factor.bf
Test: tests/hanoi.bf
Test: tests/long.bf
Test: tests/mandelbrot.bf
Test: tests/prime.bf
#####################
# End test output #
#####################
rm tests/mandelbrot.actual tests/hanoi.build tests/long.actual tests/mandelbrot.build tests/factor.actual tests/awib-0.4.actual tests/long.build tests/prime.actual tests/hanoi.expected tests/factor.build tests/awib-0.4.build tests/dbfi.expected tests/prime.build tests/mandelbrot.expected tests/dbfi.actual tests/long.expected tests/dbfi.build tests/hanoi.actual tests/factor.expected tests/prime.expected tests/awib-0.4.expected
Notice the last line rm .... Where is this coming from?

The solution is to put .SECONDARY: at the top of the makefile. More info here: http://www.thinkplexx.com/learn/howto/build-chain/make-based/prevent-gnu-make-from-always-removing-files-it-says-things-like-rm-or-removing-intermediate-files
Excerpt:
GNU make does track some files, which are created during the build,
and it will remove such files after the build. The files are called
"intermediate files". They are supposed to be created by make’s "chain
of Implicit Rules". Because they were created to facilitate something
else, make considers them useless after the build and removes them.
...
.SECONDARY with no prerequisites causes all targets to be treated as
secondary (i.e., no target is removed because it is considered
intermediate

Related

RELEASE and DEBUG build in makefile

I am developing an application for STM32 in stm32cubeIDE
I am using the below custom makefile. Now i want to have a release and a debug build, but they both build the debug build.
I´ve tried
RELDIR = bin/release
DEBUGDIR = bin/debug
ifdef DEBUG
BIN=$(DEBUGDIR)
COMPILERFLAGS += -g3 -O0 -D_DEBUG
else
BIN=$(RELDIR)
COMPILERFLAGS += -O3
endif
and
debug : rebuild
BIN=$(DEBUGDIR)
COMPILERFLAGS += -g3 -O0 -D_DEBUG
release : rebuild
BIN=$(RELDIR)
COMPILERFLAGS += -O3
Can someone tell me how to achieve a release and a debug build :)
Full script:
RED = [31m
GREEN = [32m
YELLOW = [33m
BLUE = [34m
NC = [0m
BIN = bin
SRC = src
INC = inc
SOURCE = $(wildcard $(SRC)/*.c)
OBJECT = $(patsubst %,$(BIN)/%, $(notdir $(SOURCE:.c=.o)))
COMPILER=arm-none-eabi-gcc
ARCHITECTURE=cortex-m4
COMPILERFLAGS= -c -mcpu=$(ARCHITECTURE) -mthumb -mfloat-abi=soft -std=gnu11 -Wall -I $(INC)
LINKERFLAGS= -mcpu=$(ARCHITECTURE) -mthumb -mfloat-abi=soft --specs=nano.specs --specs=rdimon.specs -lc -lrdimon --specs=nosys.specs -T stm32_linker_script.ld -Wl,-Map=out.map
COMPILE= $(COMPILER) $(COMPILERFLAGS) -o $# $<
LINK= $(COMPILER) $(LINKERFLAGS) -o $# $^
RELDIR = bin/release
DEBUGDIR = bin/debug
ifdef DEBUG
BIN=$(DEBUGDIR)
COMPILERFLAGS += -g3 -O0 -D_DEBUG
else
BIN=$(RELDIR)
COMPILERFLAGS += -O3
endif
debug : rebuild
#BIN=$(DEBUGDIR)
#COMPILERFLAGS += -g3 -O0 -D_DEBUG
#
release : rebuild
#BIN=$(RELDIR)
#COMPILERFLAGS += -O3
.PHONY: rebuild
rebuild:
$(MAKE) clean
$(MAKE) all
all : out.elf
#echo "$(GREEN)Done!$(NC)"
out.elf : $(OBJECT)
#echo "$(YELLOW)Linking...$(NC)"
$(LINK)
$(BIN)/%.o : $(SRC)/%.c
$(COMPILE)
.PHONY: all clean debug prep release remake
clean:
#echo "$(GREEN)Cleaning...$(NC)"
rm -rf $(BIN)/*.o $(BIN)/*.elf
I ended up creating two makefiles, one for debug and one for release. It is kind of anoying to have duplicated code, but at least it is obvious what is going on in each script. The scripts are then called from the IDE via "make -f Makefile.DEBUG.mk rebuild" and "make -f Makefile.REBUILD.mk rebuild"
#RED = [31m
#GREEN = [32m
#YELLOW = [33m
BLUE = [34m
NC = [0m
BIN = bin/release
SRC = src
INC = inc
MAKE = make -f Makefile.RELEASE.mk
COMPILER=arm-none-eabi-gcc
ARCHITECTURE=cortex-m4
COMPILERFLAGS= -c -mcpu=$(ARCHITECTURE) \
-mthumb -mfloat-abi=soft -std=gnu11 -Wall -O3 -I $(INC)
LINKERFLAGS= -mcpu=$(ARCHITECTURE) \
-mthumb -mfloat-abi=soft \
--specs=nano.specs \
-T stm32_linker_script.ld \
-Wl,-Map=$(BIN)/out.map
COMPILE= $(COMPILER) $(COMPILERFLAGS) -o $# $<
LINK= $(COMPILER) $(LINKERFLAGS) -o $(BIN)/$# $^
SOURCE = $(wildcard $(SRC)/*.c)
OBJECT = $(patsubst %,$(BIN)/%, $(notdir $(SOURCE:.c=.o)))
.PHONY: rebuild
rebuild:
$(MAKE) clean
$(MAKE) all
all : out.elf
#echo "$(BLUE)Done!$(NC)"
out.elf : $(OBJECT)
#echo "$(BLUE)Linking...$(NC)"
$(LINK)
$(BIN)/%.o : $(SRC)/%.c
$(COMPILE)
.PHONY: all clean
clean:
#echo "$(BLUE)Cleaning...$(NC)"
rm -rf $(BIN)/*.o $(BIN)/*.elf $(BIN)/*.map
and
#RED = [31m
#GREEN = [32m
#YELLOW = [33m
BLUE = [34m
NC = [0m
BIN = bin/debug
SRC = src
INC = inc
MAKE = make -f Makefile.DEBUG.mk
COMPILER=arm-none-eabi-gcc
ARCHITECTURE=cortex-m4
COMPILERFLAGS= -c -mcpu=$(ARCHITECTURE) \
-mthumb -mfloat-abi=soft -std=gnu11 -Wall -g -I $(INC)
LINKERFLAGS= -mcpu=$(ARCHITECTURE) \
-mthumb -mfloat-abi=soft \
--specs=nano.specs \
--specs=rdimon.specs -lc -lrdimon \
--specs=nosys.specs \
-T stm32_linker_script.ld \
-Wl,-Map=$(BIN)/out.map
COMPILE= $(COMPILER) $(COMPILERFLAGS) -o $# $<
LINK= $(COMPILER) $(LINKERFLAGS) -o $(BIN)/$# $^
SOURCE = $(wildcard $(SRC)/*.c)
OBJECT = $(patsubst %,$(BIN)/%, $(notdir $(SOURCE:.c=.o)))
.PHONY: rebuild
rebuild:
$(MAKE) clean
$(MAKE) all
all : out.elf
#echo "$(BLUE)Done!$(NC)"
out.elf : $(OBJECT)
#echo "$(BLUE)Linking...$(NC)"
$(LINK)
$(BIN)/%.o : $(SRC)/%.c
$(COMPILE)
.PHONY: all clean
clean :
#echo "$(BLUE)Cleaning...$(NC)"
rm -rf $(BIN)/*.o $(BIN)/*.elf $(BIN)/*.map

How to build a program with Make using different build configurations?

yesterday I wrote a Makefile to build a Programm which works fine.
Now, I try to build different build configurations.
What is the recommended way to build different configurations which differ in the list of source files and output paths?
I tried to use target specific variables...
Executables of the compiler toolchain.
COMPILER := ccrl
LINKER := rlink
ASSEMBLER := asrl
DEVICE_FILE := DR5F100LL.DVF
Compiler flags used to generate *.d files.
DFLAGS := \
-MM \
-MP \
-cpu=S2 \
-dev="$(DEVICE_FILE)" \
-no_warning_num=11179,11180 \
-g \
-Onothing
Compiler flags used to generate *.obj files from c source files.
CFLAGS := \
-cpu=S2 \
-c \
-dev="$(DEVICE_FILE)" \
-no_warning_num=11179,11180 \
-g \
-Onothing
Compiler flags used to generate *.obj files from assembler files.
ASMFLAGS := $(CFLAGS)
Linker flags
LDFLAGS := \
-library="${COMPILER_PATH}/lib/rl78cm4s.lib" \
-library="${COMPILER_PATH}/lib/rl78cm4r.lib" \
-library="./FFT_Library/libfft_rl78g13.lib" \
-nooptimize \
-entry=_start \
-security_id=00000000000000000000 \
-ocdbg=04 \
-user_opt_byte=EEFFE9 \
-debug \
-nocompress \
-memory=high \
-vectn=2=ffff \
-rom=.data=.dataR \
-rom=.sdata=.sdataR \
-nomessage \
-device="$(DEVICE_FILE)" \
-nologo \
-start=.const,.text,.RLIB,.SLIB,.textf,.constf,.data,.sdata/03000,.dataR,.bss/0F7F00,.sdataR,.sbss/0FFE20
Include directories
C_INCS := \
-I${COMPILER_PATH}/inc \
...
C source files used build the program.
C_SRCS_FFT_TEST := \
CodeGenerator/r_cg_cgc.c \
...
C_SRCS_HISTORY_TEST := \
CodeGenerator/r_cg_cgc.c \
...
C_SRCS_IOLINK_TEST := \
CodeGenerator/r_cg_cgc.c \
...
Assembler files used to build the program.
ASM_SRCS := \
...
Root directories of the build results.
OUT_ROOT_DIR := build
PUBLISH_ROOT_DIR := publish
.SECONDEXPANSION:
Name of the build configuration.
BUILD_CONFIG = Unknown
OUT_DIR =$(OUT_ROOT_DIR)/$(BUILD_CONFIG)
PUB_DIR =$(PUBLISH_ROOT_DIR)/$(BUILD_CONFIG)
Determine file paths of generated files.
OBJS = $(patsubst %.c,$(OUT_DIR)/%.obj,$(C_SRCS))
OBJS += $(patsubst %.asm,$(OUT_DIR)/%.obj,$(ASM_SRCS))
DEPS = $(OBJS:.obj=.d)
Filenames of the output files.
OUT_FILE = $(PUB_DIR)/MyFile.abs
MAP_FILE = $(OUT_DIR)/MyFile.map
.PHONY: build-definitions
build-definitions: fft-test history-test iolink-test
fft-test: BUILD_CONFIG=FFT_Test
fft-test: C_SRCS=$(C_SRCS_FFT_TEST)
.PHONY: fft-test
fft-test: $$(OUT_FILE)
history-test: BUILD_CONFIG=History_Test
history-test: C_SRCS=$(C_SRCS_HISTORY_TEST)
.PHONY: history-test
history-test:
#echo -e "Building $(BUILD_CONFIG)."
iolink-test: BUILD_CONFIG=IOLink_Test
iolink-test: C_SRCS=$(C_SRCS_IOLINK_TEST)
.PHONY: iolink-test
iolink-test:
#echo -e "Building $(BUILD_CONFIG)."
.PHONY: all
all: pre-build $(OUT_FILE) post-build
.PHONY: pre-build
pre-build:
#echo -e "Run pre-build target."
.PHONE: post-build
post-build:
#echo -e "Run post-build target."
.PHONY: clean
clean:
#echo -e "Run clean target."
#rm -f -v $(OUT_DIR)/LinkerSubCommand.tmp
#rm -f -v $(OBJS)
#rm -f -v $(DEPS)
#rm -f -v $(OUT_FILE)
#rm -f -v $(MAP_FILE)
How to build the dependency file from a c source file.
$(OUT_DIR)/%.d : %.c
#echo 'Building d file: $<'
#mkdir -p "$(dir $#)"
$(COMPILER) $(DFLAGS) $(C_INCS) -o "$(#:%.obj=%.d)" -MT="$#" -MT="$(#:%.obj=%.d)" "$<"
How to build the dependency file from an asm file.
$(OUT_DIR)/%.d : %.asm
#echo 'Building d file: $<'
#mkdir -p "$(dir $#)"
$(COMPILER) $(DFLAGS) $(C_INCS) -o "$(#:%.obj=%.d)" -MT="$#" -MT="$(#:%.obj=%.d)" "$<"
How to build the object file from a c source file.
$(OUT_DIR)/%.obj : %.c
#echo 'Building obj file: $<'
#mkdir -p "$(dir $#)"
$(COMPILER) $(CFLAGS) $(C_INCS) -o "$#" "$<"
#echo -e $(#:%=-input=\"%\") >> $(OUT_DIR)/LinkerSubCommand.tmp
How to build the object file from an asm file.
$(OUT_DIR)/%.obj : %.asm
#echo 'Building asm file: $<'
#mkdir -p "$(dir $#)"
$(COMPILER) $(CFLAGS) $(C_INCS) -o "$#" "$<"
#echo -e $(#:%=-input=\"%\") >> $$(OUT_DIR)/LinkerSubCommand.tmp
#
$(OBJ): %.obj: %.c $(DEPS)
How to build the output file from all object files.
%.abs : $(OBJS)
#echo -e "Building $(BUILD_CONFIG)."
#echo -e "The output directory is $(OUT_DIR)."
#echo -e "The publish directory is $(PUB_DIR)."
#echo -e "The source files are $(C_SRCS)."
#echo -e "The assembler files are $(ASM_SRCS)."
#echo -e "The generated object files are $(OBJS)."
#echo -e "Building output file is $#."
#mkdir -p "$(PUB_DIR)"
#mkdir -p "$(OUT_DIR)"
$(LINKER) $(LDFLAGS) -subcommand="$(OUT_DIR)/LinkerSubCommand.tmp" -list="$(MAP_FILE)" -output="$(OUT_FILE)"
I know that I should use private as scope of the target specific variables but than I have to download/compile a newer make Version...
I would like to know the recommended way to build such configurations.
Maybe someone can provide a simple (and complete) example?
Thanks a lot!
Michael
Makefile:
ifeq ($(config), debug)
CFLAGS := -DDEBUG -g
OUT_PATH := ./build/debug/
else ifeq ($(config), light_debug)
CFLAGS := -g
OUT_PATH := ./build/light_debug/
else #release config by default
OUT_PATH := ./build/release
endif
#...
Then make invokation is like this:
make confg=debug
or
make config=light_debug
or
make config=release

Compile two targets with one Makefile

---Full Makefile at the bottom ---
I'm currently finishing a project, so I'm coming to the packaging/compiling part.
I'm working with Make, and the specificity of my project is that it contains two projects with a main() in each of them.
I want a binary of the first project (named 'shell') and a binary of the second one (named 'ls'). I've edited the Makefile to separate targets, sources files, etc. Here are the important lines:
-- Projects --
TARGET_SHELL = shell
TARGET_LS = ls
-- Directories --
SOURCE = ./src
BIN = ./bin
DIRLIST = ${SOURCE} ${BIN}
-- Targets --
BINSHELL = ${TARGET_SHELL:%=${BIN}/%}
BINLS = ${TARGET_LS:%=${BIN}/%}
-- Files --
SRC_SHELL = ${wildcard ${SOURCE}/execution.c ${SOURCE}/shell.c}
SRC_LS = ${wildcard ${SOURCE}/commande_ls.c}
INT_SHELL = ${wildcard ${SOURCE}/execution.h}
INT_LS = ${wildcard ${SOURCE}/commande_ls.h}
OBJ_SHELL = ${SRC_SHELL:%.c=%.o}
OBJ_LS = ${SRC_LS:%.c=%.o}
-- Rules --
all : ${BINSHELL} ${BINLS}
-- Binaries --
${BIN}/${TARGET_SHELL} : ${${TARGET_SHELL}:%=${SOURCE}/%}
${BIN}/${TARGET_LS} : ${${TARGET_LS}:%=${SOURCE}/%}
${BIN}/% : $(OBJ_SHELL)
#echo
#echo Linking bytecode : $#
#echo ----------------
#echo
${CC} -o $# $^ ${LDFLAGS}
#echo
#echo Done
#echo
The 'make' command works perfectly. At the end, I have two binaries, one named 'shell' and the other one named 'ls'. Nice!
But in fact, the two binaries are exactly the same, they both execute the 'shell' project. I wanted the binary 'shell' to execute the 'shell' project, and the binary named 'ls' to execute the 'ls' project...
I know that I have to edit the end of the Makefile, but I don't know what :(
Thanks
#/// #file
#/// #brief Generic Makefile for the System 2 project.
#
#/// #detail If you just add some library files used by the project.c program, you have nothing to change to compile them if sources are in the ./src directory. To add a new binary, just add the name of the main file in the TARGETS variable.
#Nom du project
TARGET_SHELL = shell
TARGET_LS = ls
##############
# Constantes #
##############
# Repertoires
SOURCE = ./src
BIN = ./bin
DOCPATH = ${SOURCE}/dox
DOCTARGET = ./doc
DIRLIST = ${SOURCE} ${BIN}
#DEP = ${SOURCE}/depend
#DIRLIST = ${SOURCE} ${BIN} ${OPT} ${DEP}
# Cibles
BINSHELL = ${TARGET_SHELL:%=${BIN}/%}
BINLS = ${TARGET_LS:%=${BIN}/%}
# Commandes
CC = gcc
# Options
CFLAGS = -O0 -g -W -Wall -Wextra -Wconversion -Werror -mtune=native -march=native -std=c99 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700
LDFLAGS = -lm -W -Wall -pedantic -L. -lm
# Fichiers
DOX = ${wildcard ${DOCPATH}/*.dox} # Sources
SRC_SHELL = ${wildcard ${SOURCE}/divers.c ${SOURCE}/commandes_externes.c ${SOURCE}/commandes_internes.c ${SOURCE}/entities.c ${SOURCE}/execution.c ${SOURCE}/parse.c ${SOURCE}/shell.c} # Sources
SRC_LS = ${wildcard ${SOURCE}/commande_ls.c}
INT_SHELL = ${wildcard ${SOURCE}/divers.h ${SOURCE}/commandes_externes.h ${SOURCE}/commandes_internes.h ${SOURCE}/execution.h ${SOURCE}/parse.h} # Interfaces
INT_LS = ${wildcard ${SOURCE}/commande_ls.h}
OBJ_SHELL = ${SRC_SHELL:%.c=%.o} # Objets
OBJ_LS = ${SRC_LS:%.c=%.o}
##########
# Regles #
##########
# ALL
all : ${BINSHELL} ${BINLS}
# CLEAN
clean :
#echo
#echo Cleaning : object files
#echo --------
#echo
rm -f ${OBJ_SHELL}
rm -f ${OBJ_LS}
clean-doc :
#echo
#echo Cleaning : object files
#echo --------
#echo
rm -fr ${DOCTARGET}
clean-emacs :
#echo
#echo Cleaning : emacs back-ups
#echo --------
#echo
rm -f ${SOURCE}/*~
rm -f ${SOURCE}/\#*\#
rm -f *~
rm -f \#*\#
clean-bin :
#echo
#echo Cleaning : binaries
#echo --------
#echo
rm -f ${BINSHELL}
rm -f ${BINLS}
distclean : clean clean-emacs clean-bin
dirs :
#for dir in ${DIRLIST} ;\
do \
echo Creating directory : $${dir} ;\
echo ------------------ ;\
if test -d $${dir} ;\
then \
echo Directory already exists ;\
else mkdir -p $${dir} ;\
fi ;\
echo Done ;\
echo ;\
done
# Binaires
${BIN}/${TARGET_SHELL} : ${${TARGET_SHELL}:%=${SOURCE}/%}
${BIN}/${TARGET_LS} : ${${TARGET_LS}:%=${SOURCE}/%}
${BIN}/% : $(OBJ_SHELL)
#echo
#echo Linking bytecode : $#
#echo ----------------
#echo
${CC} -o $# $^ ${LDFLAGS}
#echo
#echo Done
#echo
# Regles generiques
%.o : %.c %.h
#echo
#echo Compiling $#
#echo --------
#echo
$(CC) $(CFLAGS) -c $< -o $#
# Documentation
doc : ${SRC} ${INT} ${DOX}
doxygen; doxygen
#############################
# Inclusion et spécificités #
#############################
.PHONY : all clean clean-doc clean-emacs clean-bin distclean doc
Some fun with very dynamic makefile:
#
# Boilerplate.
#
define add_target
$(info add_target($1))
$(eval $(eval_args))
$(eval $(call eval_args,$1,\
OBJDIR := $(firstword $($1.OBJDIR) ./objs/$1),\
))
$(eval $(call eval_args,$1,\
objs := $(obj_from_source),
))
$(eval $1 := $($1.TARGET))
TARGETS += $($1)
PHONY_TARGETS += $1
CLEAN_TARGETS += clean_$1
.PHONY: clean_$1
clean_$1:; rm -rf $($1.OBJDIR) $($1)
.PHONY: $1
$1: $($1)
$($1): target:=$1
$($1): $($1.objs); $$(if $$(wildcard $$(#D)),,mkdir -p $$(#D) && )$$(add_target.link)
$($1.objs):; $$(if $$(wildcard $$(#D)),,mkdir -p $$(#D) && )$$(add_target.compile)
$(foreach $1.SOURCES,$($1.SOURCES),$(eval $(obj_from_source): $($1.SOURCES)))
$(info end)
endef
void :=
space := $(void) $(void)
obj_from_source = $(addprefix $($1.OBJDIR)/,$(addsuffix .o,$(basename $(notdir $($1.SOURCES)))))
eval_args = $(foreach i,2 3 4 5 6 7 8 9,$(call eval_arg,$1,$(strip $($i))))
eval_arg = $(if $2,$(info $(space)$(space)$1.$2)$(eval $1.$2))
# Link command line
add_target.link = $(CC) $($(target).LDLAGS) -o $# $^
# Compile command line
add_target.compile = $(CC) -c -o $# $($(target).CFLAGS) $<
# -- Directories --
SOURCE := ./src
BIN := ./bin
# Add 'shell' target to the project
$(eval $(call add_target,shell,\
TARGET := $(BIN)/shell,\
SOURCES += ${SOURCE}/execution.c,\
SOURCES += ${SOURCE}/shell.c,\
CFLAGS := -Wall -I./include,\
))
# Add 'ls' target to the project
$(eval $(call add_target,ls,\
TARGET := $(BIN)/ls,\
SOURCES := $(addprefix ${SOURCE}/,execution.c commande_ls.c),\
CFLAGS := -I./include,\
))
all: ${PHONY_TARGETS}
.PHONY: all
clean: | $(CLEAN_TARGETS)
.PHONY: clean
Environment:
$ find
.
./include
./include/execution.h
./src
./src/commande_ls.c
./src/execution.c
./src/shell.c
Source files:
$ for f in `find -type f`; do echo $f; cat $f; echo; done
./include/execution.h
void workload();
./src/commande_ls.c
#include <stdio.h>
#include "execution.h"
int main() {
printf("Welcome to ls\n");
workload();
}
./src/execution.c
#include <stdio.h>
#include "execution.h"
void workload() {
printf("Hello from %s\n", __FILE__);
}
./src/shell.c
#include <stdio.h>
#include "execution.h"
int main() {
printf("Welcome to shell\n");
workload();
}
Build all targets:
$ make -f ../Makefile.sample
add_target(shell)
shell.TARGET := ./bin/shell
shell.SOURCES += ./src/execution.c
shell.SOURCES += ./src/shell.c
shell.CFLAGS := -Wall -I./include
shell.OBJDIR := ./objs/shell
shell.objs := $(obj_from_source)
end
add_target(ls)
ls.TARGET := ./bin/ls
ls.SOURCES := ./src/execution.c ./src/commande_ls.c
ls.CFLAGS := -I./include
ls.OBJDIR := ./objs/ls
ls.objs := $(obj_from_source)
end
mkdir -p objs/shell && cc -c -o objs/shell/execution.o -Wall -I./include src/execution.c
cc -c -o objs/shell/shell.o -Wall -I./include src/shell.c
mkdir -p bin && cc -o bin/shell objs/shell/execution.o objs/shell/shell.o
mkdir -p objs/ls && cc -c -o objs/ls/execution.o -I./include src/execution.c
cc -c -o objs/ls/commande_ls.o -I./include src/commande_ls.c
cc -o bin/ls objs/ls/execution.o objs/ls/commande_ls.o
Run targets:
$ ./bin/ls.exe; ./bin/shell.exe
Welcome to ls
Hello from src/execution.c
Welcome to shell
Hello from src/execution.c
Clean ls and build all targets again (just for fun):
$ make -f ../Makefile.sample clean_ls
add_target(shell)
shell.TARGET := ./bin/shell
shell.SOURCES += ./src/execution.c
shell.SOURCES += ./src/shell.c
shell.CFLAGS := -Wall -I./include
shell.OBJDIR := ./objs/shell
shell.objs := $(obj_from_source)
end
add_target(ls)
ls.TARGET := ./bin/ls
ls.SOURCES := ./src/execution.c ./src/commande_ls.c
ls.CFLAGS := -I./include
ls.OBJDIR := ./objs/ls
ls.objs := $(obj_from_source)
end
rm -rf ./objs/ls ./bin/ls
$ make -f ../Makefile.sample
add_target(shell)
shell.TARGET := ./bin/shell
shell.SOURCES += ./src/execution.c
shell.SOURCES += ./src/shell.c
shell.CFLAGS := -Wall -I./include
shell.OBJDIR := ./objs/shell
shell.objs := $(obj_from_source)
end
add_target(ls)
ls.TARGET := ./bin/ls
ls.SOURCES := ./src/execution.c ./src/commande_ls.c
ls.CFLAGS := -I./include
ls.OBJDIR := ./objs/ls
ls.objs := $(obj_from_source)
end
mkdir -p objs/ls && cc -c -o objs/ls/execution.o -I./include src/execution.c
cc -c -o objs/ls/commande_ls.o -I./include src/commande_ls.c
cc -o bin/ls objs/ls/execution.o objs/ls/commande_ls.o
Note how handy $(add_target) function is. It provides way add as many targets to your project as you need without stupid code duplication. Still configuring of target build options is extremely flexible.
Should work with GNU Make 3.81 and up. Enjoy!
Did you try something like this:
SUBDIRS := common programs
all: subdir
ifdef SUBDIRS
.PHONY: subdir $(SUBDIRS)
subdir: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -s -C $# <-- ${BIN...
endif
SUBDIRS --> TARGET...

Gfortran compiling error after replacing with f77

QI need to compile some files using gfortran. I went to the makefile and replaced all the "f77" with "gfortran". However I get this error when I do "make"
gfortran -c verbal.f
gfortran -c trgl6_octa.f
gfortran -c trgl6_icos.f
gfortran -c gauss_trgl.f
gfortran -c gauss_leg.f
gfortran -c sgf_3d_fs.f
gfortran -c sgf_3d_w.f
f77 -c -o sgf_3d_2p_w.o sgf_3d_2p_w.f
make: f77: Command not found
make: *** [sgf_3d_2p_w.o] Error 127
I do not understand where in the make file (pasted below) there is a hidden f77 that did not get replaced. I checked all the sources files for "f77" and there was none. I am very confused.
#
# Objects
# -------
#
OBJ0 = verbal.o
OBJ1 = trgl6_octa.o trgl6_icos.o gauss_trgl.o gauss_leg.o
OBJ2 = sgf_3d_fs.o sgf_3d_w.o sgf_3d_2p_w.o
OBJ2A = sgf_3d_3p.o sgf_3d_3p_ewald.o sgf_3d_3p_qqq.o
OBJ3 = prtcl_3d_mob.o
OBJ30 = elm_geom.o abc.o interp_p.o printel.o
OBJ33 = slp_trgl6.o slp_trgl6_sing.o slp_trgl3_sing.o
OBJ4 = gel.o gel_inv.o
OBJ = $(OBJ0) $(OBJ1) $(OBJ2) $(OBJ2A) $(OBJ3) $(OBJ30) $(OBJ33) $(OBJ4)
#
# link
# ----
#
prtcl_3d_mob: $(OBJ)
gfortran -c prtcl_3d_mob $(OBJ)
#
# compile
# ------
#
prtcl_3d_mob.o: prtcl_3d_mob.f
gfortran -c prtcl_3d_mob.f
trgl6_octa.o: trgl6_octa.f
gfortran -c trgl6_octa.f
trgl6_icos.o: trgl6_icos.f
gfortran -c trgl6_icos.f
verbal.o: verbal.f
gfortran -c verbal.f
sgf_3d_fs.o: sgf_3d_fs.f
gfortran -c sgf_3d_fs.f
sgf_3d_w.o: sgf_3d_w.f
gfortran -c sgf_3d_w.f
sgf_3d_3p.o: sgf_3d_3p.f
gfortran -c sgf_3d_3p.f
sgf_3d_3p_ewald.o: sgf_3d_3p_ewald.f
gfortran -c sgf_3d_3p_ewald.f
sgf_3d_3p_qqq.o: sgf_3d_3p_qqq.f
gfortran -c sgf_3d_3p_qqq.f
gel.o: gel.f
gfortran -c gel.f
gel_inv.o: gel_inv.f
gfortran -c gel_inv.f
prtcl_3d_geo.o: prtcl_3d_geo.f
gfortran -c prtcl_3d_geo.f
interp_p.o: interp_p.f
gfortran -c interp_p.f
abc.o: abc.f
gfortran -c abc.f
printel.o: printel.f
gfortran -c printel.f
elm_geom.o: elm_geom.f
gfortran -c elm_geom.f
slp_trgl6.o: slp_trgl6.f
gfortran -c slp_trgl6.f
slp_trgl6_sing.o: slp_trgl6_sing.f
gfortran -c slp_trgl6_sing.f
slp_trgl3_sing.o: slp_trgl3_sing.f
gfortran -c slp_trgl3_sing.f
gauss_leg.o: gauss_leg.f
gfortran -c gauss_leg.f
gauss_trgl.o: gauss_trgl.f
gfortran -c gauss_trgl.f
#
# clean
# -----
#
clean:
rm -f core
rm -f $(OBJ) prtcl_3d_mob
rm -f prtcl_3d_mob.net prtcl_3d_mob.out
rm -f matrix_inverse.out
rm -f particle_elements.out
#
# purge
# ---
#
purge:
rm -f core
rm -f $(OBJ) prtcl_3d_mob
rm -f prtcl_3d_mob.net prtcl_3d_mob.out
rm -f matrix_inverse.out
rm -f particle_elements.out
#
# clobber
# ---
#
clobber:
rm *
#
# all
# ---
#
all:
make prtcl_3d_mob
GNU make has a number of implicit rules https://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules
By default, it will compile .f files with the rule $(FC) $(FFLAGS) -c where by default FC is set to f77 (see link above for all of this).
As an explicit rule ("from .f to .o") is not found for a file, make invokes the default rule.
Solutions: either one of the two
Set FC to gfortran
add an explicit rule for sgf_3d_2p_w.o
In general, I write the rule myself as
%.o: %.f90
$(FC) $(FFLAGS) -c $<
in the Makefile. It makes it obvious that I need to define FC and FFLAGS.
Also, you can then remove all of the individual rules for compiling your files.

Makefile dependency issue

I'm trying to compile an example code where I added a new file under a new directory but I keep getting a dependency problem.
I have added a file "ipc.c" under "/interface".
I have added the source file to "srcs" and also added the directory with "-I/interface".
The Makefile looks as follows:
#
# ======== Makefile ========
#
include ../products.mak
srcs = main_host.c interface/ipc.c
objs = $(addprefix bin/$(PROFILE)/obj/,$(patsubst %.c,%.o$(SUFFIX),$(srcs)))
libs = $(SYSLINK_INSTALL_DIR)/packages/ti/syslink/lib/syslink.a_$(PROFILE)
MAKEVARS = \
SYSLINK_INSTALL_DIR=$(SYSLINK_INSTALL_DIR) \
PKGPATH=$(PKGPATH)
all:
#$(ECHO) "!"
#$(ECHO) "! Making $# ..."
$(MAKE) $(MAKEVARS) PROFILE=debug SUFFIX=v5T togs2_host
$(MAKE) $(MAKEVARS) PROFILE=release SUFFIX=v5T togs2_host
install:
#$(ECHO) "#"
#$(ECHO) "# Making $# ..."
#$(MKDIR) $(INSTALL_DIR)/debug
$(CP) bin/debug/togs2_host $(INSTALL_DIR)/debug
#$(MKDIR) $(INSTALL_DIR)/release
$(CP) bin/release/togs2_host $(INSTALL_DIR)/release
clean::
$(RMDIR) bin
#
#
# ======== rules ========
#
togs2_host: bin/$(PROFILE)/togs2_host
bin/$(PROFILE)/togs2_host: $(objs) $(libs)
#$(ECHO) "##"
#$(ECHO) "## Making $# ..."
$(LD) $(LDFLAGS) -o $# $^ $(LDLIBS)
bin/$(PROFILE)/obj/%.o$(SUFFIX): %.h
bin/$(PROFILE)/obj/%.o$(SUFFIX): %.c
#$(ECHO) "###"
#$(ECHO) "### Making $# ..."
$(CC) $(CPPFLAGS) $(CFLAGS) -o $# $<
# ======== create output directories ========
ifneq (clean,$(MAKECMDGOALS))
ifneq (,$(PROFILE))
ifeq (,$(wildcard bin/$(PROFILE)))
$(shell $(MKDIR) -p bin/$(PROFILE))
endif
ifeq (,$(wildcard bin/$(PROFILE)/obj))
$(shell $(MKDIR) -p bin/$(PROFILE)/obj)
endif
endif
endif
# ======== install validation ========
ifeq (install,$(MAKECMDGOALS))
ifeq (,$(INSTALL_DIR))
$(error must specify INSTALL_DIR)
endif
endif
# ======== toolchain macros ========
ifeq (v5T,$(SUFFIX))
CC = $(CS_ARM_INSTALL_DIR)gcc -c -MD -MF $#.dep -march=armv5t
AR = $(CS_ARM_INSTALL_DIR)ar cr
LD = $(CS_ARM_INSTALL_DIR)gcc
CPPFLAGS = -D_REENTRANT -Dxdc_target_name__=GCArmv5T \
-Dxdc_target_types__=gnu/targets/arm/std.h
CFLAGS = -Wall -ffloat-store -fPIC -Wunused -Dfar= $(CCPROFILE_$(PROFILE)) \
-I. -I/interface $(addprefix -I,$(subst +, ,$(PKGPATH)))
LDFLAGS = $(LDPROFILE_$(PROFILE)) -Wall -Wl,-Map=$#.map
LDLIBS = -lpthread -lc
CCPROFILE_debug = -ggdb -D DEBUG
CCPROFILE_release = -O3 -D NDEBUG
LDPROFILE_debug = -ggdb
LDPROFILE_release = -O3
endif
I keep getting this error:
fatal error: opening dependency file bin/debug/obj/interface/ipc.ov5T.dep: No such file or directory
This is how the the products.mak looks like:
#
# ======== products.mak ========
#
DEPOT = /opt
BIOS_INSTALL_DIR = $(DEPOT)/bios_6_33_01_25
IPC_INSTALL_DIR = $(DEPOT)/ti/ipc_1_23_05_40
SYSLINK_INSTALL_DIR = $(DEPOT)/syslink_2_10_02_17
TI_C6X_INSTALL_DIR = $(DEPOT)/ti/ccsv5/tools/compiler/c6000
CS_ARM_INSTALL_DIR = $(DEPOT)/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-
XDC_INSTALL_DIR = $(DEPOT)/xdctools_3_23_00_32
PKGPATH := $(SYSLINK_INSTALL_DIR)/packages
PKGPATH := $(PKGPATH)+$(BIOS_INSTALL_DIR)/packages
PKGPATH := $(PKGPATH)+$(IPC_INSTALL_DIR)/packages
PKGPATH := $(PKGPATH)+$(XDC_INSTALL_DIR)/packages
PKGPATH := $(PKGPATH)+$
# Use this goal to print your product variables.
.show-products:
#echo "BIOS_INSTALL_DIR = $(BIOS_INSTALL_DIR)"
#echo "IPC_INSTALL_DIR = $(IPC_INSTALL_DIR)"
#echo "SYSLINK_INSTALL_DIR = $(SYSLINK_INSTALL_DIR)"
#echo "TI_ARM_INSTALL_DIR = $(TI_ARM_INSTALL_DIR)"
#echo "TI_C6X_INSTALL_DIR = $(TI_C6X_INSTALL_DIR)"
#echo "CS_ARM_INSTALL_DIR = $(CS_ARM_INSTALL_DIR)"
#echo "XDC_INSTALL_DIR = $(XDC_INSTALL_DIR)"
# ======== standard macros ========
ifneq (,$(wildcard $(XDC_INSTALL_DIR)/bin/echo.exe))
# use these on Windows
CP = $(XDC_INSTALL_DIR)/bin/cp
ECHO = $(XDC_INSTALL_DIR)/bin/echo
MKDIR = $(XDC_INSTALL_DIR)/bin/mkdir -p
RM = $(XDC_INSTALL_DIR)/bin/rm -f
RMDIR = $(XDC_INSTALL_DIR)/bin/rm -rf
else
# use these on Linux
CP = cp
ECHO = echo
MKDIR = mkdir -p
RM = rm -f
RMDIR = rm -rf
endif
I'm not understanding the Makefile completely as it's a code example I'm simply expanding.
For the record: The error "fatal error: opening dependency file [...]: No such file or directory" can also be caused by a too long path. Happened to me on Cygwin/Windows with a path that was way over 200 characters (didn't check exactly).
Got it working.
Needed to add a rule to create the output directories.
So I added
ifeq (,$(wildcard bin/$(PROFILE)/obj/interface))
$(shell $(MKDIR) -p bin/$(PROFILE)/obj/interface)
endif
This makefile is pretty convoluted, so a certain amount of guesswork is required, but I think the trouble is that it doesn't know how to find interface/ipc.c. Try adding this line at the bottom and see if helps:
vpath %.c interface
If it doesn't, we can try some other things. (And if it does, I can suggest some ways to simplify the makefile.)

Resources