Make file for compilation of many files - makefile

I have a makefile already written and all the libraries as I need, can anybody redact it correctly with the right tabulations and structure:
# Macros
CC = gcc
COMP_FLAG = -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG
LIB_FLAG = -L. -lmtm
# Main target
tests: memcache_test my_set_test cache_test user_test
# Targets make <file>
user_test: user_test.o user.o
$(CC) user_test.o user.o $(LIB_FLAG) -o $#
memcache_test: memcache_test.o memcache.o user.o cache.o
$(CC) memcache_test.o memcache.o user.o cache.o $(LIB_FLAG) -o $#
cache_test: cache_test.o cache.o
$(CC) cache_test.o cache.o $(LIB_FLAG) -o $#
my_set_test: my_set_test.o my_set.o
$(CC) my_set_test.o my_set.o -o $#
# Targets make <file>_test.o
user_test.o: tests/user_test.c user.h tests/test_utilities.h map.h set.h
$(CC) -c $(COMP_FLAG) $(LIB_FLAG) tests/$*.c
memcache_test.o: tests/memcache_test.c tests/test_utilities.h memcache.h map.h cache.h set.h list.h
$(CC) -c $(COMP_FLAG) $(LIB_FLAG) tests/$*.c
cache_test.o: tests/cache_test.c cache.h tests/test_utilities.h set.h
$(CC) -c $(COMP_FLAG) $(LIB_FLAG) tests/$*.c
my_set_test.o: my_set/my_set_test.c tests/test_utilities.h my_set/my_set.h
$(CC) -c $(COMP_FLAG) $(LIB_FLAG) my_set/$*.c
# Targets make <file>.o
memcache.o: memcache.c memcache.h map.h cache.h list.h set.h user.h
$(CC) -c $(COMP_FLAG) $(LIB_FLAG) $*.c
user.o: user.c user.h set.h map.h
$(CC) -c $(COMP_FLAG) $(LIB_FLAG) $*.c
cache.o: cache.c cache.h set.h
$(CC) -c $(COMP_FLAG) $(LIB_FLAG) $*.c
my_set.o: my_set/my_set.c my_set/my_set.h
$(CC) -c $(COMP_FLAG) my_set/$*.c
# Target runs all test files
run: run_my_set_test run_cache_test run_memcache_test run_user_test
run_clean: clean run
run_my_set_test: my_set_test
./my_set_test
run_cache_test: cache_test
./cache_test
run_memcache_test: memcache_test
./memcache_test
run_user_test: user_test
./user_test
# Target remove all <*_test> and <*.o> files
clean: clean_o clean_test
clean_test:
rm -f *_test
clean_o:
rm -f *.o
When I try to run it, it says:
***** missing separator. Stop.
I don't know how and where to put the separators.

Each rule in the makefile is a line with a colon (':'), followed by optional lines that are commands. Each command must begin with a tab:
user_test: user_test.o user.o
$(CC) user_test.o user.o $(LIB_FLAG) -o $#
Is that sufficient explanation?

Related

makefile for two compilers

I would like to make a single makefile for two compilers. I like the example Intel has in its oneAPI, see below. Basically, under each target rule, it has explicit compilation rules. But my makefile is like:
# compile old fortran files
$(BLD)/%.o: $(SRC)/%.for
$(FC) -c $(FFLAGS) -o $# $<
# compile new fortran files
$(BLD)/%.o: $(SRC)/%.f90
$(FC) -c $(FFLAGS) -o $# $<
# link everything
$(target): $(objects)
$(FC) -o $# $(FFLAGS) -I $(BLD) $^ $(LDFLAGS)
I saw that one way would be to change the $(FC) variable plus the flags to appropriate values in a target. The advantage of the Intel that one can very specifically change the additional switches so if for gfortran i have the line $(FC) -o $# $(FFLAGS) -I $(BLD) $^ $(LDFLAGS) what if I need this to look like $(FC) -o $# $(FFLAGS) -J $(BLD) $^ $(LDFLAGS) for ifort etc. Is there a way to make a rule within another rule so something that would look like:
GFORT_EXE = $(target).gfort
IFORT_EXE = $(target).ifort
#
gfort: $(GFORT_EXE)
ifort: $(IFORT_EXE)
$(GFORT_EXE):
$(BLD)/%.o: $(SRC)/%.for
$(FC) -c $(FFLAGS) -o $# $<
# compile new fortran files
$(BLD)/%.o: $(SRC)/%.f90
$(FC) -c $(FFLAGS) -o $# $<
# link everything
$(FC) -o $# $(FFLAGS) -I $(BLD) $^ $(LDFLAGS)
Or what is the best way to approach it if i need the command line to look different in principal for each compiler?
The intel makefile:
# Copyright Intel Corporation 2014
#
# To compile with the GNU* C/C++ compiler, creating an execution file with the
# extension ".gcc" for binary instrumentation, issue:
#
# > make
#
# To compile with the Intel(R) C++ Compiler for Linux*, creating an execution
# file with the extension ".icc":
#
# Source <path_to_compiler_bin>/compilervars.sh or iccvars.csh;
#
# > make icc
#
# To compile with the Intel(R) C++ Compiler for Linux* with Intel(R) MKL library
# creating an executionfile with the extension ".mkl":
#
# Source <path_to_compiler_bin>/compilervars.sh or iccvars.csh;
#
# > make mkl
#
# To compile with the Intel(R) C++ Compiler for Linux to cross compile for the
# Intel(R) Xeon Phi(TM) coprocessor, creating an execution file with the
# extension ".mic":
#
# Source <path_to_compiler_bin>/compilervars.sh intel64
#
# > make mic
#
# To compile them all, use the source line from the Intel MIC architecture
# option above, then type:
#
# > make all
SHELL = /bin/sh
PARAMODEL = -DUSE_THR # Default parallelism using pthreads/Win threads
#PARAMODEL = -DUSE_OMP -fopenmp # Use OpenMP for multithreading
GCC = gcc
ICC = icc
CFLAGS = -g -O3 -fno-asm
OPTFLAGS = -xSSE3
# OPTFLAGS = -xHost -fno-alias
# add -DALIGNED to the multiply.c and matrix.c
LDFLAGS = -lpthread -lm
GCFLAGS = $(CFLAGS) $(PARAMODEL)
ICFLAGS = $(CFLAGS) $(PARAMODEL)-DICC -debug inline-debug-info #-vec-report3 -qopt-report -qopt-report-phase=vec
MKFLAGS = $(CFLAGS) -DUSE_MKL -DICC -mkl -debug inline-debug-info
GCC_EXE = matrix.gcc
ICC_EXE = matrix.icc
MKL_EXE = matrix.mkl
srcdir = ../src
gcc: $(GCC_EXE)
icc: $(ICC_EXE)
mkl: $(MKL_EXE)
all: $(GCC_EXE) $(ICC_EXE) $(MKL_EXE)
OBJS = util.o thrmodel.o multiply.o matrix.o
matrix.gcc: $(srcdir)/matrix.c $(srcdir)/multiply.c $(srcdir)/multiply.h $(srcdir)/util.c $(srcdir)/thrmodel.c
$(GCC) $(GCFLAGS) -c $(srcdir)/util.c -D_LINUX
$(GCC) $(GCFLAGS) -c $(srcdir)/thrmodel.c -D_LINUX
$(GCC) $(GCFLAGS) -c $(srcdir)/multiply.c -D_LINUX
$(GCC) $(GCFLAGS) -c $(srcdir)/matrix.c -D_LINUX
$(GCC) $(GCFLAGS) -g $(OBJS) -o ../matrix $(LDFLAGS)
matrix.icc: $(srcdir)/matrix.c $(srcdir)/multiply.c $(srcdir)/multiply.h $(srcdir)/util.c $(srcdir)/thrmodel.c
$(ICC) $(ICFLAGS) -c $(srcdir)/util.c -D_LINUX
$(ICC) $(ICFLAGS) -c $(srcdir)/thrmodel.c -D_LINUX
$(ICC) $(ICFLAGS) $(OPTFLAGS) -c $(srcdir)/multiply.c -D_LINUX
$(ICC) $(ICFLAGS) $(OPTFLAGS) -c $(srcdir)/matrix.c -D_LINUX
$(ICC) $(ICFLAGS) $(OBJS) -o ../matrix $(LDFLAGS)
matrix.mkl: $(srcdir)/matrix.c $(srcdir)/multiply.c $(srcdir)/multiply.h $(srcdir)/util.c $(srcdir)/thrmodel.c
$(ICC) $(MKFLAGS) -c $(srcdir)/util.c -D_LINUX
$(ICC) $(MKFLAGS) -c $(srcdir)/thrmodel.c -D_LINUX
$(ICC) $(MKFLAGS) $(OPTFLAGS) -c $(srcdir)/multiply.c -D_LINUX
$(ICC) $(MKFLAGS) $(OPTFLAGS) -c $(srcdir)/matrix.c -D_LINUX
$(ICC) $(MKFLAGS) $(OBJS) -o ../matrix $(LDFLAGS)
clean:
#rm -rf $(OBJS) $(GCC_EXE) $(ICC_EXE) $(MKL_EXE)
# * Other names and brands may be claimed as the property of others.
No, you can't redefine a rule within a rule (and quite frankly, you wouldn't want to, as there's tons of sharp sticks with this sort of approach, which you would be guaranteed to trip over). I would suggest for something like this you do two separate output directories, and have the rules based on the output directory, as so:
objects := ...
FC_gfort := ...
FC_ifort := ...
$(BLD)/gfort/%.o: $(SRC)/%.for
$(FC_gfort) -c $(FFLAGS) -o $# $<
$(BLD)/gfort/%.o: $(SRC)/%.f90
$(FC_gfort) -c $(FFLAGS) -o $# $<
$(BLD)/ifort/%.o: $(SRC)/%.for
$(FC_ifort) -c $(FFLAGS) -o $# $<
$(BLD)/ifort/%.o: $(SRC)/%.f90
$(FC_gfort) -c $(FFLAGS) -o $# $<
# link everything
$(target).gfort: $(BLD)/gfort/$(objects)
$(FC_gfort) -o $# $(FFLAGS) -J $(BLD)/gfort $^ $(LDFLAGS)
$(target).ifort: $(BLD)/ifort/$(objects)
$(FC_ifort) -o $# $(FFLAGS) -I $(BLD)/ifort $^ $(LDFLAGS)
Now, if you have lots of rules, and this gets to repetitive, you can use a define and eval, as so instead:
LINK_FLAG_gfort:=-J
LINK_FLAG_ifort:=-I
define RULES_template =
$$(BLD)/$(1)/%.o: $$(SRC)/%.for
$$(FC_$(1)) -c $$(FFLAGS) -o $$# $$<
$$(BLD)/$(1)/%.o: $$(SRC)/%.f90
$$(FC_$(1)) -c $$(FFLAGS) -o $$# $$<
$$(target).$(1): $$(BLD)/$(1)/$$(objects)
$$(FC_$(1)) -o $$# $$(FFLAGS) $$(LINK_FLAG_$(1)) $$(BLD)/$(1) $^ $$(LDFLAGS)
endef
$(eval $(call RULES_template,ifort))
$(eval $(call RULES_template,gfort))
Note the double $$'s in here (but not in front of $(1)...)
Also, I mentioned sharp sticks with your original idea, where you override the rule -- say you build ifort, and then did a subsequent build of gfort, with no clean in between. The .o files would not be rebuilt, as the timestamps would be newer than the sources', but the linker would run and use the obsolete artifacts.
Hope this helps

Makefile: How to place auto-generated files in a separate directory?

You can see my Makefile here:
....
PHY_SRCS = ../LwMesh/phy/at86rf212/src/phy.c
HAL_SRCS = ../LwMesh/hal/atmega1281/src/hal.c ../LwMesh/hal/atmega1281/src/halPhy.c ../LwMesh/hal/atmega1281/src/halTimer.c
SYS_SRCS = ../LwMesh/sys/src/sys.c ../LwMesh/sys/src/sysEncrypt.c ../LwMesh/sys/src/sysTimer.c
....
# define the C object files
PHY_OBJS = $(PHY_SRCS:.c=.o)
HAL_OBJS = $(HAL_SRCS:.c=.o)
....
# define the executable file
PHY = phy_cc
HAL = hal_cc
SYS = sys_cc
.....
OBJDIR := obj
$(OBJDIR):
mkdir $(OBJDIR)
all: $(PHY) $(HAL) $(SYS) $(DRV) $(NWK) $(SRV) $(VELA)
#echo Alles wurde Kompiliert
$(PHY): $(PHY_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(PHY) $(PHY_OBJS) $(LFLAGS)
$(HAL): $(HAL_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(HAL) $(HAL_OBJS) $(LFLAGS)
....
.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
...
I have tried too much to place auto-generated files (e.g. object files) in a separate directory(OBJDIR), but I did not find any solution.
I referred to this tutorial, but it is not suitable for my Makefile.
Could you please help me?
Let's take this in small steps.
You already have a rule for building object files:
.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
Which can be written out as:
%.o: %.c
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
This will use ../LwMesh/phy/at86rf212/src/phy.c to build ../LwMesh/phy/at86rf212/src/phy.c. But imagine for a moment that phy.c were in the working directory. Then Make could use that rule to build phy.o from phy.c. In that case we could make a small change in the rule:
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
and Make would build obj/phy.o.
How do we tell Make where to find phy.c? There are two good ways. One is using vpath:
vpath %.c ../LwMesh/phy/at86rf212/src
After we confirm that this works, we can add other directories for other sets of objects (such as PHY and SYS):
vpath %.c ../LwMesh/phy/at86rf212/src ../LwMesh/hal/atmega1281/src ../LwMesh/sys/src ...
Now all we have to do is construct the lists of objects correctly:
PHY_OBJS = phy.o
HAL_OBJS = hal.o halPhy.o halTimer.o
SYS_OBJS = sys.o sysEncrypt.o sysTimer.o
...
Once this much is working correctly, further refinements are possible.
You can see the corrected Makefile here:
# define compiler type
CC = avr-gcc
# define any compile-time flags
CFLAGS = -Wall -g -funsigned-char -funsigned-bitfields -DPHY_AT86RF212 -DHAL_ATMEGA1281 -DPLATFORM_ANY900_STICK -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -g2 -Wall -mmcu=atmega1281 -c -std=gnu99 -MD -MP -MF "$(#:%.o=%.d)" -MT"$(#:%.o=%.d)" -MT"$(#:%.o=%.o)"
# define any directories containing header files other than /usr/include
INCLUDES += \
-I"../LwMesh/hal/atmega1281/inc" \
-I"../LwMesh/hal/drivers/atmega1281" \
-I"../LwMesh/phy/at86rf212/inc" \
-I"../LwMesh/nwk/inc" \
-I"../LwMesh/sys/inc" \
-I"../LwMesh/service/inc" \
-I"../common" \
-I".." \
-I.
# define library paths in addition to /usr/lib
LFLAGS = -L/home/newhall/lib -L../lib
# define any libraries to link into executable:
LIBS = -lmylib -lm
# define the C source files
PHY_SRCS = ../LwMesh/phy/at86rf212/src/phy.c
HAL_SRCS = ../LwMesh/hal/atmega1281/src/hal.c ../LwMesh/hal/atmega1281/src/halPhy.c ../LwMesh/hal/atmega1281/src/halTimer.c
SYS_SRCS = ../LwMesh/sys/src/sys.c ../LwMesh/sys/src/sysEncrypt.c ../LwMesh/sys/src/sysTimer.c
DRV_SRCS = ../LwMesh/hal/drivers/atmega1281/halUart.c ../LwMesh/hal/drivers/atmega1281/halTwi.c
NWK_SRCS += \
../LwMesh/nwk/src/nwk.c \
../LwMesh/nwk/src/nwkDataReq.c \
../LwMesh/nwk/src/nwkSecurity.c \
../LwMesh/nwk/src/nwkFrame.c \
../LwMesh/nwk/src/nwkGroup.c \
../LwMesh/nwk/src/nwkRoute.c \
../LwMesh/nwk/src/nwkRouteDiscovery.c \
../LwMesh/nwk/src/nwkRx.c \
../LwMesh/nwk/src/nwkTx.c
SRV_SRCS = ../LwMesh/service/src/otaClient.c ../LwMesh/service/src/otaServer.c
VELA_SRCS += \
base-commands.c \
bus-commands.c \
bus-interface.c \
host-interface.c \
measurement.c \
VelaMain.c \
otaInterface.c \
persistence.c \
shell.c
PHY_OBJS = $(addprefix $(OBJDIR)/PHY/,phy.o)
HAL_OBJS = $(addprefix $(OBJDIR)/HAL/,hal.o halPhy.o halTimer.o)
SYS_OBJS = $(addprefix $(OBJDIR)/SYS/,sys.o sysEncrypt.o sysTimer.o)
DRV_OBJS = $(addprefix $(OBJDIR)/DRV/,halUart.o halTwi.o)
NWK_OBJS = $(addprefix $(OBJDIR)/NWK/,nwk.o nwkDataReq.o nwkSecurity.o nwkFrame.o nwkGroup.o nwkRoute.o nwkRouteDiscovery.o nwkRx.o nwkTx.o)
SRV_OBJS = $(addprefix $(OBJDIR)/SRV/,otaClient.o otaServer.o)
VELA_OBJS = $(addprefix $(OBJDIR)/VELA/,base-commands.o bus-commands.o bus-interface.o host-interface.o measurement.o VelaMain.o otaInterface.o persistence.o shell.o)
# define the executable file
PHY = phy_cc
HAL = hal_cc
SYS = sys_cc
DRV = drv_cc
NWK = nwk_cc
SRV = srv_cc
VELA = vela_cc
OBJDIR := objdir
OUTPUT_FILE_PATH +=Vela2.elf
OUTPUT_FILE_PATH_AS_ARGS +=Vela2.elf
OUTPUT_FILE_DEP:=
ALL_OBJS := $(PHY_OBJS) $(HAL_OBJS) $(SYS_OBJS) $(DRV_OBJS) $(NWK_OBJS) $(SRV_OBJS) $(VELA_OBJS)
ALL_SRCS := $(PHY_SRCS) $(HAL_SRCS) $(SYS_SRCS) $(DRV_SRCS) $(NWK_SRCS) $(SRV_SRCS) $(VELA_SRCS)
$(OUTPUT_FILE_PATH): $(ALL_OBJS) $(OUTPUT_FILE_DEP)
#echo Invoking: AVR/GNU Linker
$(CC) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(ALL_OBJS) -Wl,-Map="Vela2.map" -Wl,-u,vfprintf -Wl,--start-group -Wl,--end-group -Wl,--gc-sections -mrelax -mmcu=atmega1281
#echo Finished building target: $#
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "Vela2.elf" "Vela2.hex"
avr-objcopy -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "Vela2.elf" "Vela2.eep" || exit 0
avr-objdump -h -S "Vela2.elf" > "Vela2.lss"
avr-objcopy -O srec -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "Vela2.elf" "Vela2.srec"
avr-size "Vela2.elf"
$(OBJDIR)/PHY/%.o : ../LwMesh/phy/at86rf212/src/%.c
$(CC) $(CFLAGS) $(INCLUDES) $(OUTPUT_OPTION) $<
$(OBJDIR)/HAL/%.o : ../LwMesh/hal/atmega1281/src/%.c
$(CC) $(CFLAGS) $(INCLUDES) $(OUTPUT_OPTION) $<
$(OBJDIR)/SYS/%.o : ../LwMesh/sys/src/%.c
$(CC) $(CFLAGS) $(INCLUDES) $(OUTPUT_OPTION) $<
$(OBJDIR)/DRV/%.o : ../LwMesh/hal/drivers/atmega1281/%.c
$(CC) $(CFLAGS) $(INCLUDES) $(OUTPUT_OPTION) $<
$(OBJDIR)/NWK/%.o : ../LwMesh/nwk/src/%.c
$(CC) $(CFLAGS) $(INCLUDES) $(OUTPUT_OPTION) $<
$(OBJDIR)/SRV/%.o : ../LwMesh/service/src/%.c
$(CC) $(CFLAGS) $(INCLUDES) $(OUTPUT_OPTION) $<
$(OBJDIR)/VELA/%.o : %.c
$(CC) $(CFLAGS) $(INCLUDES) $(OUTPUT_OPTION) $<
all: $(ALL_OBJS) $(OUTPUT_FILE_PATH)
$(ALL_OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir -p objdir/PHY
mkdir -p objdir/HAL
mkdir -p objdir/SYS
mkdir -p objdir/DRV
mkdir -p objdir/NWK
mkdir -p objdir/SRV
mkdir -p objdir/VELA
$(PHY): $(PHY_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(PHY) $(PHY_OBJS) $(LFLAGS)
$(HAL): $(HAL_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(HAL) $(HAL_OBJS) $(LFLAGS)
$(SYS): $(SYS_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(SYS) $(SYS_OBJS) $(LFLAGS)
$(DRV): $(DRV_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(DRV) $(DRV_OBJS) $(LFLAGS)
$(NWK): $(NWK_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(NWK) $(NWK_OBJS) $(LFLAGS)
$(SRV): $(SRV_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(SRV) $(SRV_OBJS) $(LFLAGS)
$(VELA): $(VELA_OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(VELA) $(VELA_OBJS) $(LFLAGS)
clean:
-$(RM) $(OBJS_AS_ARGS) $(EXECUTABLES)
-$(RM) $(C_DEPS_AS_ARGS)
rm -rf "Vela2.elf" "Vela2.a" "Vela2.hex" "Vela2.lss" "Vela2.eep" "Vela2.map" "Vela2.srec" "Vela2.usersignatures"
depend: $(PHY_SRCS) $(HAL_SRCS) $(SYS_SRCS) $(DRV_SRCS) $(NWK_SRCS) $(SRV_SRCS) $(VELA_SRCS)
makedepend $(INCLUDES) $^

makefile with 2 executables, how?

My project is organized like this :
src/plateau.c plateau.h tuile.c tuile.h main.c
tests/tests.c
obj/
bin/
I'm trying to do a makefile with 2 executables. I can't figure out why it doesn't works.
The makefile with one executable only works fine, it looks like this :
CC = gcc -Wall -Wextra -ansi
SRCDIR = src
OBJDIR = obj
BINDIR = bin
DOXYGEN = doxygen
all: honshu
honshu: $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o honshu
$(OBJDIR)/plateau.o: $(SRCDIR)/plateau.c $(SRCDIR)/plateau.h
$(CC) -c $(SRCDIR)/plateau.c -o $(OBJDIR)/plateau.o
$(OBJDIR)/tuile.o: $(SRCDIR)/tuile.c $(SRCDIR)/tuile.h
$(CC) -c $(SRCDIR)/tuile.c -o $(OBJDIR)/tuile.o
$(OBJDIR)/main.o: $(SRCDIR)/main.c
$(CC) -c -I src $(SRCDIR)/main.c $# -lm
doxygen:
$(DOXYGEN) -g
$(DOXYGEN) Doxyfile
clean:
rm *.o
rm honshu
And with two executables, I tried like this :
CC = gcc -Wall -Wextra -ansi
SRCDIR = src
OBJDIR = obj
BINDIR = bin
DOXYGEN = doxygen
all: honshu tests
honshu: $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/main.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o honshu
tests: $(OBJDIR)/test_honshu.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o
$(CC) $(OBJDIR)/test_honshu.o $(OBJDIR)/plateau.o $(OBJDIR)/tuile.o -o tests
$(OBJDIR)/plateau.o: $(SRCDIR)/plateau.c $(SRCDIR)/plateau.h
$(CC) -c $(SRCDIR)/plateau.c -o $(OBJDIR)/plateau.o
$(OBJDIR)/tuile.o: $(SRCDIR)/tuile.c $(SRCDIR)/tuile.h
$(CC) -c $(SRCDIR)/tuile.c -o $(OBJDIR)/tuile.o
$(OBJDIR)/main.o: $(SRCDIR)/main.c
$(CC) -c -I src $(SRCDIR)/main.c $# -lm
$(OBJDIR)/test_honshu.o: $(SRCDIR)/test_honshu.c
$(CC) -c -I src $(SRCDIR)/test_honshu.c $# -lm
doxygen:
$(DOXYGEN) -g
$(DOXYGEN) Doxyfile
clean:
rm *.o
rm honshu
But I have the following message "no rules to make "src/test_honshu.c", necessary for "obj.test_honshu.o", do you have an idea ? Thanks !

Project Makefile problems with Google Test

For the life of me I cannot figure out how to remove the mv statements in the following makefile
TEST_DIR = ../gtest
USER_DIR = src
TESTS_DIR = tests
OBJ_DIR = obj
CPPFLAGS += -isystem $(GTEST_DIR)/include -I$(USER_DIR)
CXXFLAGS += -g -Wall -Wextra
TESTS = test
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
$(GTEST_DIR)/include/gtest/internal/*.h
all : $(TESTS)
clean :
rm -rf obj
rm -rf bin
mkdir obj
mkdir bin
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
$(OBJ_DIR)/gtest-all.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest-all.cc
mv gtest-all.o obj/gtest-all.o
$(OBJ_DIR)/gtest_main.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest_main.cc
mv gtest_main.o obj/gtest_main.o
$(OBJ_DIR)/gtest.a : $(OBJ_DIR)/gtest-all.o
$(AR) $(ARFLAGS) $# $^
$(OBJ_DIR)/gtest_main.a : $(OBJ_DIR)/gtest-all.o $(OBJ_DIR)/gtest_main.o
$(AR) $(ARFLAGS) $# $^
$(OBJ_DIR)/addition.o : $(USER_DIR)/addition.cpp $(USER_DIR)/addition.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
mv addition.o obj/addition.o
$(OBJ_DIR)/test.o : $(TESTS_DIR)/test.cpp $(USER_DIR)/addition.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TESTS_DIR)/test.cpp
mv test.o obj/test.o
test : $(OBJ_DIR)/addition.o $(OBJ_DIR)/test.o $(OBJ_DIR)/gtest_main.a
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $#
The problem is the mv test.o obj/test.o line and the others like it. I know there is a way to have make do this automatically for you but for the life of me I cannot find/figure it out.
This is the precanned makefile that comes with google test that I have modified to work for me.
Something like
CPPFLAGS += -MMD -MP
gtest_objs := $(OBJ_DIR)/gtest_all.o $(OBJ_DIR)/gtest_main.o
my_objs := $(OBJ_DIR)/addition.o $(OBJ_DIR)/test.o
all_objs := $(gtest_objs) $(objs)
deps := $(all_objs:.o=.d)
$(gtest_objs): CPPFLAGS += -I$(GTEST_DIR)
$(gtest_objs): $(OBJ_DIR)/gtest_%.o: $(GTEST_DIR)/src/gtest_%.cc
$(my_objs): $(OBJ_DIR)/%.o: $(USER_DIR)/%.cpp
$(all_objs):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
-include $(deps)
The rule for all_objs is copied from the builtin rule, and the deps-related stuff will generate dependencies for you automatically.

change of header file detection for makefile

My makefile doesn't detect changes in header files. How can i add this functionality to my makefile? Here is my makefile:
CPP = g++
CC = gcc
RES =
OBJ = obj/main.o obj/customfunc1.o obj/customfunc2.o $(RES)
LINKOBJ = obj/main.o obj/customfunc1.o obj/customfunc2.o $(RES)
LIBS =
INCS = -I"lib1/inc" -I"lib2/inc"
CXXINCS = -I"lib1/inc" -I"lib2/inc"
BIN = out
CXXFLAGS = $(CXXINCS)
CFLAGS = $(INCS)
RM = rm -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o $(BIN) $(LIBS)
obj/main.o: main.c
$(CC) -c main.c -o obj/main.o $(CFLAGS)
obj/customfunc1.o: lib1/customfunc1.c
$(CC) -c lib1/customfunc1.c -o obj/customfunc1.o $(CFLAGS)
obj/customfunc2.o: lib2/customfunc2.c
$(CC) -c lib2/customfunc2.c -o obj/customfunc2.o $(CFLAGS)
Header files must be listed together with other dependencies. E.g.:
CPP = g++
CC = gcc
RES =
OBJ = obj/main.o obj/customfunc1.o obj/customfunc2.o $(RES)
LINKOBJ = obj/main.o obj/customfunc1.o obj/customfunc2.o $(RES)
LIBS =
INCS = -I"lib1/inc" -I"lib2/inc"
CXXINCS = -I"lib1/inc" -I"lib2/inc"
BIN = out
CXXFLAGS = $(CXXINCS)
CFLAGS = $(INCS)
RM = rm -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o $(BIN) $(LIBS)
obj/main.o: main.c header1.h header2.h
$(CC) -c main.c -o obj/main.o $(CFLAGS)
obj/customfunc1.o: lib1/customfunc1.c lib1/header.h
$(CC) -c lib1/customfunc1.c -o obj/customfunc1.o $(CFLAGS)
obj/customfunc2.o: lib2/customfunc2.c lib2/header.h
$(CC) -c lib2/customfunc2.c -o obj/customfunc2.o $(CFLAGS)

Resources