makefile for two compilers - makefile

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

Related

ERROR: rm: cannot remove 'kernel.img': No such file or directory

I've been trying to get my Raspberry Pi 4 OS (not Linux or anything, I'm making an OS from scratch) to work.
The Makefile has this error when I use the command "make":
rm -rf objects
rm -rf SuperPiOS.elf
rm SuperPiOS.img
rm: cannot remove 'SuperPiOS.img': No such file or directory
make: *** [Makefile:110: clean] Error 1
I can't figure out why it wouldn't work though.
Here's the Makefile:
CFLAGS= -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
CXXFLAGS= -ggdb3 -O0 -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
CSRCFLAGS= -O2 -Wall -Wextra
LFLAGS= -ffreestanding -O2 -nostdlib
IMG_PATH= ../
CFILES= $(wildcard *.c)
OFILES= $(CFILES:.c=.o)
GCCFLAGS= -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
GCCPATH= gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf
GCCPATHAARCH= $(GCCPATH)/aarch64-none-elf/bin
GCCPATHBIN= $(GCCPATH)/bin
ASMCFLAGS= -f elf32 -F dwarf -g -w+all
ASM= -s
# Location of the files
KER_SRC = ../src/kernel
KER_MENU_SRC = ../src/kernel/menu
KER_HEAD = ../include
COMMON_SRC = ../src/common
UI_IMAGES = ../images/ui
SPE_GAMES = ../spe_games
DINOBYTE = $(SPE_GAMES)/dinobyte
OBJ_DIR = objects
ASMSOURCES = $(wildcard $(KER_SRC)/*.s)
KERSOURCES = $(wildcard $(KER_SRC)/*.c)
#KERSOURCES = $(wildcard $(KER_SRC)/$(ARCHDIR)/*.c)
COMMONSOURCES = $(wildcard $(COMMON_SRC)/*.c)
KERSOURCESCPP = $(wildcard $(KER_SRC)/*.cpp)
DINOBYTESOURCES = $(wildcard $(DINOBYTE)/src/*.cpp)
#KERSOURCESCPP = $(wildcard $(KER_SRC)/$(ARCHDIR)/*.cpp)
#KERMENUSOURCESC = $(wildcard $(KER_MENU_SRC)/*.c)
#KERMENUSOURCESCPP = $(wildcard $(KER_MENU_SRC)/*.cpp)
UISOURCES = $(wildcard $(UI_IMAGES)/*.png)
OBJECTS = $(patsubst $(KER_SRC)/%.s, $(OBJ_DIR)/%.o, $(ASMSOURCES))
#OBJECTS += $(patsubst $(KER_SRC)/%.s, $(OBJ_DIR)/%.o, $(ASMSOURCES))
OBJECTS += $(patsubst $(KER_SRC)/%.c, $(OBJ_DIR)/%.o, $(KERSOURCES))
OBJECTS += $(patsubst $(KER_SRC)/%.cpp, $(OBJ_DIR)/%.o, $(KERSOURCESCPP))
OBJECTS += $(patsubst $(COMMON_SRC)/%.c, $(OBJ_DIR)/%.o, $(COMMONSOURCES))
#OBJECTS += $(patsubst $(KER_MENU_SRC)/%.c, $(OBJ_DIR)/%.o, $(KERMENUSOURCESC))
#OBJECTS += $(patsubst $(KER_MENU_SRC)/%.cpp, $(OBJ_DIR)/%.o, $(KERMENUSOURCESCPP))
#OBJECTS += $(patsubst $(UI_IMAGES)/%.png, $(OBJ_DIR)/%.o, $(UISOURCES))
#Dinobyte objects [include Dinobyte headers here] (do later)
#OBJECTS += $(patsubst $(DINOBYTESOURCES)/src/%.cpp, $(OBJ_DIR)/%.o, $(DINOBYTESOURCES))
#Headers
HEADERS = $(wildcard $(KER_HEAD)/*.h)
IMG_NAME=SuperPiOS
#build: $(OBJECTS) $(HEADERS)
#$(CC) -T linker.ld -o $(IMG_NAME).elf $(LFLAGS) $(OBJECTS) #needs indent
#$(OBJCOPY) $(IMG_NAME).elf -O binary $(IMG_NAME).img #needs indent
#$(OBJ_DIR)/%.o: $(KER_SRC)/%.s
#mkdir -p $(#D) #needs indent
#$(CC) $(CFLAGS) -I$(KER_SRC) -c $< -o $# #needs indent
$(OBJ_DIR)/%.o: $(KER_SRC)/%.s
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $(KER_SRC) -o $(OBJ_DIR)
$(OBJ_DIR)/%.o: $(KER_SRC)/%.c
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $#
$(OBJ_DIR)/%.o: $(KER_SRC)/$(ARCHDIR)/%.c
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $#
$(OBJ_DIR)/%.o: $(KER_SRC)/%.cpp
$(GCCPATHBIN) arm-none-eabi-cpp $(GCCFLAGS) -c $< -o $#
$(OBJ_DIR)/%.o: $(KER_SRC)/$(ARCHDIR)/%.cpp
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $#
$(OBJ_DIR)/%.o: $(COMMON_SRC)/%.c
$(GCCPATHBIN)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $#
#$(OBJ_DIR)/%.o: $(KER_MENU_SRC)/%.c
# mkdir -p $(#D)
# $(CC) $(CFLAGS) -I$(KER_SRC) -I$(KER_HEAD) -c $< -o $# $(CSRCFLAGS)
#$(OBJ_DIR)/%.o: $(KER_MENU_SRC)/%.cpp
# mkdir -p $(#D)
# $(CC) $(CXXFLAGS) -I$(KER_SRC) -I$(KER_HEAD) -c $< -o $# $(CSRCFLAGS)
$(IMG_NAME)%.img: $(OBJECTS) $(HEADERS)
$(GCCPATHBIN)/aarch64-none-elf-ld -nostdlib -nostartfiles $(OBJECTS) -T linker.ld -o $(IMG_NAME).elf
$(GCCPATHBIN)/aarch64-none-elf-objcopy -O binary $(IMG_NAME).elf $(IMG_NAME).img
clean:
rm -rf $(OBJ_DIR)
rm -rf $(IMG_NAME).elf
rm $(IMG_NAME).img
run: build
qemu-system-arm -m 128 -no-reboot -M raspi4 -serial stdio -kernel kernel.elf
dbg:
$(GDB) kernel.elf
dbgrun: build gdbinit
qemu-system-arm -m 128 -no-reboot -M raspi4 -serial stdio -kernel kernel.elf -S -s
.PHONY: gdbinit
gdbinit:
echo "target remote localhost:1234" > .gdbinit
echo "break kernel_main" >> .gdbinit
You have two problems. The most obvious one is that this command:
rm SuperPiOS.img
is failing because that's how the rm program is defined: if the file you ask it to delete doesn't exist then rm will fail. If you don't want that to happen, add the -f option:
rm -f SuperPiOS.img
Now if the file doesn't exist, rm will silently succeed. You can examine the man pages for the rm program.
However, the higher level question you are probably asking is, why when I run make is it running the clean rule?
That's because make, if you don't specify what to build on the command line, always builds the first explicit target. In this makefile the first explicit target you defined is clean, so that's what's built. This is almost certainly not what you want. You should figure out what target you want to build when you run make with no arguments and put the rule for that target as the first explicit target in your makefile.
Other than this rule it normally doesn't matter much what order rules come in (if you have multiple pattern rules that could all build the same target, for example multiple pattern rules to build %.o, then order can matter there).

GNU make linker input file unused because linking not done

I have some troubles with my make file. All the output files are generated, but linking is not possible. Therefore, I don't get the output executable. Where is my mistake?
Here is my recipe for the output file:
gcc main.o memory.o startup_msp432p401r_gcc.o system_msp432p401r.o interrupts_msp432p401r_gcc.o -Wall -Werror -g -O0 -std=c99 -DHOST -MM -Wl,-Map=c1m2.map -T msp432p401r.lds -o c1m2.out
And here is the whole makefile:
ifeq ($(PLATFORM),HOST)
CC = gcc
else
CC = arm-none-eabi-gcc
endif
# Architectures Specific Flags
LINKER_FILE = msp432p401r.lds
CPU = cortex-m4
ARCH = mthumb
SPECS = nosys.specs
# Compiler Flags and Defines
LD = arm-none-eabi-ld
ifeq ($(PLATFORM),MSP432)
CFLAGS = -Wall -Werror -g -O0 -std=c99 -mcpu=cortex-m4 -mthumb -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 --specs=nosys.specs
LDFLAGS = -T msp432p401r.lds
else
CFLAGS = -Wall -Werror -g -O0 -std=c99 -DHOST
LDFLAGS = -Wl,-Map=$(TARGET).map -T msp432p401r.lds
endif
TARGET = c1m2
CPPFLAGS = -MM
OBJS = $(SOURCES:.c=.o)
%.o: %.c
$(CC) $< $(CFLAGS) $(CPPFLAGS) -o $#
.PHONY: build
build: all
.PHONY: all
all: $(TARGET).out
$(TARGET).out: $(OBJS)
$(CC) $(OBJS) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $#
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET).out $(TARGET).map
Thank you very much!

What does “linker input file unused because linking not done” mean?

This is weird. The compiler throws this warning though everything works as expected.
This is the makefile that throws the warning:
TARGET = $(notdir $(shell pwd))
LIBS = -lm -lev3dev-c
D_BIN = Build-Assets
ifeq ($(OS),Windows_NT)
LIBS := $(LIBS) -lws2_32
D_BIN := $(D_BIN)/mingw
endif
D_H = ../../source/ev3
CFLAGS = $(addprefix -I, $(D_H)) -O2 -std=gnu99 -W -Wall -Wno-comment
ifeq ($(OS),Windows_NT)
CC = gcc
else
CC = arm-linux-gnueabi-gcc
endif
ifeq ($(OS),Windows_NT)
E_BIN = .exe
else
E_BIN =
endif
F_BIN = $(TARGET)$(E_BIN)
OBJECTS = $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard MotorControl/*.c)))
.PHONY: default all clean
default: $(F_BIN)
all: default
$(OBJECTS): $(D_BIN)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
.PRECIOUS: $(F_BIN) $(OBJECTS)
$(F_BIN): $(OBJECTS)
$(CC) $(OBJECTS) -c -Wall $(LIBS) -o $#
clean:
-rm -f $(D_BIN)/*.o
-rm -f $(F_BIN)
I should add that I have no idea what I'm doing... I am just starting out with C and those damn makefiles are very overwhelming.
The -c option skips the final link and produces a relocatable object file:
$(F_BIN): $(OBJECTS)
$(CC) $(OBJECTS) -c -Wall $(LIBS) -o $#
This is why linker input files are not used at this stage. You should be able to remove the -c option, and the command will produce an executable as a result.

Not able to include a library in makefile

I am kind of new in the use of make.
I have a library written in C which is in the folder folder1
Where these files are there is also a makefile which is the following:
PREFIX ?= /usr/local
CC = gcc
AR = ar
CFLAGS = -std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4
APRILTAG_SRCS := $(shell ls *.c common/*.c)
APRILTAG_HEADERS := $(shell ls *.h common/*.h /usr/include/flycapture/*.h)
APRILTAG_OBJS := $(APRILTAG_SRCS:%.c=%.o)
TARGETS := libapriltag.a libapriltag.so
.PHONY: all
all: $(TARGETS)
#$(MAKE) -C example all
.PHONY: install
install: libapriltag.so
#chmod +x install.sh
#./install.sh $(PREFIX)/lib libapriltag.so
#./install.sh $(PREFIX)/include/apriltag $(APRILTAG_HEADERS)
#sed 's:^prefix=$$:prefix=$(PREFIX):' < apriltag.pc.in > apriltag.pc
#./install.sh $(PREFIX)/lib/pkgconfig apriltag.pc
#rm apriltag.pc
#ldconfig
libapriltag.a: $(APRILTAG_OBJS)
#echo " [$#]"
#$(AR) -cq $# $(APRILTAG_OBJS)
libapriltag.so: $(APRILTAG_OBJS)
#echo " [$#]"
#$(CC) -fPIC -shared -o $# $^
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS)
.PHONY: clean
clean:
#rm -rf *.o common/*.o $(TARGETS)
#$(MAKE) -C example clean
Then, in the folder example I have some example which I can just run by giving the following command in the terminal:
./opencv_demo
or
./apriltag_demo
In this folder example I have another makefile which is the following:
CC = gcc
CXX = g++
CPPFLAGS = -I..
CFLAGS = -std=gnu99 -Wall -Wno-unused-parameter -Wno-unused-function -O4
CXXFLAGS = -Wall -O4
LDFLAGS = -Lusr/include/flycapture -lpthread -lm
INC_DIR = /usr/include/flycapture
TARGETS := apriltag_demo opencv_demo
.PHONY: all
all: apriltag_demo opencv_demo
apriltag_demo: apriltag_demo.o ../libapriltag.a
#echo " [$#]"
#$(CC) -o $# $^ $(LDFLAGS)
opencv_demo: opencv_demo.o ../libapriltag.a /usr/include/flycapture/Error.h
#echo " [$#]"
#$(CXX) -o $# $^ $(LDFLAGS) `pkg-config --libs opencv`
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS) $(CPPFLAGS)
%.o: %.cc
#echo " $#"
#$(CXX) -o $# -c $< $(CXXFLAGS) $(CPPFLAGS)
.PHONY: clean
clean:
#rm -rf *.o $(TARGETS)
If I do make in the folder1 I get the following error:
opencv_demo.o: In function `main':
opencv_demo.cc:(.text.startup+0x24e): undefined reference to `FlyCapture2::Error::Error()'
opencv_demo.cc:(.text.startup+0x2a7): undefined reference to `FlyCapture2::Error::~Error()'
opencv_demo.cc:(.text.startup+0x11a0): undefined reference to `FlyCapture2::Error::~Error()'
collect2: error: ld returned 1 exit status
make[1]: *** [opencv_demo] Error 1
make[1]: Leaving directory `/home/fschiano/Repositories/apriltag2/example'
make: *** [all] Error 2
If I am not wrong this error tells me that I did not include a library.
In the file opencv_demo.cc I did:
#include "flycapture/FlyCapture2.h"
#include "flycapture/Error.h"
using namespace FlyCapture2;
Headers which are in /usr/include/flycapture a folder which contains all the headers needed for what I need in the file opencv_demo.cc.
I don't know why it is not working, someone is able to help me?
I think I should write in the makefile where to search for the libraries but I don't know how.
I tried to write the following things in the makefile separately but they are not working :
LDFLAGS = -Lusr/include/flycapture -lpthread -lm
INC_DIR = /usr/include/flycapture
DEPS = $(INC_DIR)/Error.h

Make file for compilation of many files

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?

Resources