I need a Makefile can be used to build a project with this kind of structure :
Multiple source folders.
all objects in a output dir.
Multiple corresponding target folders for object and dependency files.
│─inc
└─src
│ ├─lib1
│ │ ├─inc
│ │ └─src
│ ├─lib2
│ │ ├─inc
│ │ └─src
│ └─main.c
│
└─output
└─src
├─lib1
│ └─src
│ ├─ lib1_file1.o
│ └─ lib1_file2.o
├─lib2
│ └─src
│ ├─ lib2_file1.o
│ └─ lib2_file2.o
└─main.o
I tried this one, but not work.
LIBNAME=libhello.a
OUTDIR=output
CC = gcc
CFLAGS = -Wall -MD -O2 -c
LFLAGS =
INCS = -Iinc \
-Isrc/lib1/inc \
-Isrc/lib2/inc
SOURCES = src/main.c \
src/lib1/lib1_file1.c \
src/lib1/lib1_file2.c \
src/lib2/lib2_file1.c \
src/lib2/lib2_file2.c
OBJS=$(SOURCES:%.c=${OUTDIR}/%.o)
all: ${LIBNAME}
${LIBNAME}: ${OBJS}
ar crs ${OUTDIR}/$# $^
.PYONY: clean
clean:
#rm -rf ${OUTDIR}
${OUTDIR}/%.o:%.c
#mkdir -p $(#D)
#${CC} ${CFLAGS} ${INCS} $< -o $# ${LFLAGS}
Your makefile will work correctly if you give it the correct source paths. You gave it this:
SOURCES = ... src/lib1/lib1_file1.c ...
but the actual path in your directory structure is:
SOURCES = ... src/lib1/src/lib1_file1.c ...
Related
I am writing a Makefile for a project where all the cpp files are in subdirectories and some of them contains spaces:
└── L0/
│ └──── Commodities API/
│ │ └──── commodities_api.h
│ └──── Communication API/
│ │ └──── communication_api.h
│ └──── L0 Base/
│ │ ├──── L0_base.cpp
│ │ └──── L0_base.h
│ └──── Provision API/
│ │ └──── provision_api.h
│ ├──── L0_commodities.cpp
│ ├──── L0_communication.cpp
│ ├──── L0.cpp
│ ├──── L0_enumerations.h
│ ├──── L0_error_manager.h
│ ├──── L0.h
│ ├──── L0_provision.cpp
This is my Makefile 'til now:
CPP = g++
LFLAGS +=
CFLAGS += -g -MMD
INCLUDES +=
CPP_SRCS := $(shell find sources -name '*.cpp' | sort | uniq | sed 's/ /\\\\ /g')
CPP_DIRS := $(shell find sources -name '*.cpp' -printf '%h\n' | sort | uniq | sed 's/ /\\\\ /g')
OBJS := $(CPP_SRCS:.cpp=.o)
OUT_DIR := out
all:
#echo $(CPP_SRCS)
#echo
#echo $(OBJS)
#echo
#echo $(CPP_DIRS)
lib.so: $(OBJS)
%.o: %.cpp Makefile
#echo "[C] $<"
$(CPP) -c $(CFLAGS) $(INCLUDES) "$<"
This is the output from the "all" target, used to print the three variables:
sources/L0/L0\ Base/L0_base.cpp sources/L0/L0_commodities.cpp sources/L0/L0_communication.cpp sources/L0/L0.cpp sources/L0/L0_provision.cpp sources/L1/Crypto\ Libraries/aes256.cpp sources/L1/L1\ Base/L1_base.cpp sources/L1/L1.cpp sources/L1/L1_login_logout.cpp sources/L1/L1_security.cpp sources/L1/L1_sekey.cpp
sources/L0/L0\ Base/L0_base.o sources/L0/L0_commodities.o sources/L0/L0_communication.o sources/L0/L0.o sources/L0/L0_provision.o sources/L1/Crypto\ Libraries/aes256.o sources/L1/L1\ Base/L1_base.o sources/L1/L1.o sources/L1/L1_login_logout.o sources/L1/L1_security.o sources/L1/L1_sekey.o
sources/L0 sources/L0/L0\ Base sources/L1 sources/L1/Crypto\ Libraries sources/L1/L1\ Base
But when I try to launch make lib.so
make: *** No rule to make target 'sources/L0/L0\', needed by 'lib.so'. Stop.
What can I do to solve this problem? Thanks!
Make use spaces as list delimiter, and there is no good way to escape it (pun intended). Your options include:
Replace the spaces with something else, like dash or underscore
Migrate from Make to e.g. CMake or SCons
For Windows you can reference any file or directory by its short path which is guaranteed not having spaces, see https://superuser.com/questions/348079/how-can-i-find-the-short-path-of-a-windows-directory-file.
i'm doing a static library in asm and i'm trying to use its fonctions after in a c main.
I don't understand why, during the make test rule, the linkage doesnt work since i checked the library dir with -L. and the include dir with -I ./include, as well as the lib itself with -static and -lasm
What can i change ?
Here is my Makefile :
NAME = libasm.a
SRC = ft_write.s \
ft_read.s \
ft_strcmp.s \
ft_strcpy.s \
ft_strdup.s \
ft_strlen.s
SRC_BONUS = ft_atoi_base.s \
ft_list_push_front.s \
ft_list_size.s \
ft_list_sort.s \
ft_list_remove_if.s
SRC_DIR = ./srcs
CC = clang
CFLAGS = -v -L. -I$(INCLUDE) -static -Wall -Wextra -Werror -lasm
NASM = nasm
NASMFLAGS = -f elf64
INCLUDE = ./include
OBJ_DIR = ./objs
OBJ = $(patsubst %.s, ${OBJ_DIR}/%.o, ${SRC})
OBJ_BONUS = $(OBJ) $(patsubst %.s, ${OBJ_DIR}/%.o, ${SRC_BONUS})
BIN = test
all : $(NAME)
$(NAME) : $(OBJ)
ar rcs $# $^
ranlib $(NAME)
#echo "$(NAME) has been created"
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.s
mkdir -p $(OBJ_DIR)
#echo "\033[0;32mGenerating binary..."
$(NASM) $(NASMFLAGS) $< -o $#
#echo "\033[0m"
test : main.c $(NAME)
$(CC) $< $(CFLAGS) -o $(BIN)
./$(BIN)
bonus : $(OBJ_BONUS)
ar rcs $(NAME) $^
ranlib $(NAME)
#echo "$(NAME) with bonus has been created"
clean :
rm -f $(OBJ_BONUS)
fclean : clean
rm -f $(NAME)
rm -f $(BIN)
and the trace : the problem is the undefined reference (référence indéfinie)
clang main.c -v -g -L. -I./include -static -Wall -Wextra -Werror -lasm -o test
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0
Candidate multilib: .;#m64
Selected multilib: .;#m64
"/usr/lib/llvm-6.0/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name main.c -static-define -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -v -resource-dir /usr/lib/llvm-6.0/lib/clang/6.0.0 -I ./include -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-6.0/lib/clang/6.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wall -Wextra -Werror -fdebug-compilation-dir /home/salty/Documents/libasm -ferror-limit 19 -fmessage-length 106 -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/main-559408.o -x c main.c
clang -cc1 version 6.0.0 based upon LLVM 6.0.0 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
./include
/usr/local/include
/usr/lib/llvm-6.0/lib/clang/6.0.0/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
"/usr/bin/ld" -z relro --hash-style=gnu -m elf_x86_64 -static -o test /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/crtbeginT.o -L. -L/usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../.. -L/usr/lib/llvm-6.0/bin/../lib -L/lib -L/usr/lib /tmp/main-559408.o -lasm --start-group -lgcc -lgcc_eh -lc --end-group /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../x86_64-linux-gnu/crtn.o
/tmp/main-559408.o : Dans la fonction « check_strlen » :
libasm/main.c:13 : référence indéfinie vers « ft_strlen »
/tmp/main-559408.o : Dans la fonction « check_strcmp » :
libasm/main.c:22 : référence indéfinie vers « ft_strcmp »
/tmp/main-559408.o : Dans la fonction « check_strdup » :
libasm/main.c:33 : référence indéfinie vers « ft_strdup »
/tmp/main-559408.o : Dans la fonction « strdup_test » :
libasm/main.c:42 : référence indéfinie vers « ft_strdup »
/tmp/main-559408.o : Dans la fonction « check_strcpy » :
libasm/main.c:61 : référence indéfinie vers « ft_strcpy »
libasm/main.c:64 : référence indéfinie vers « ft_strcpy »
/tmp/main-559408.o : Dans la fonction « strcpy_test » :
libasm/main.c:75 : référence indéfinie vers « ft_strcpy »
libasm/main.c:94 : référence indéfinie vers « ft_strcpy »
libasm/main.c:98 : référence indéfinie vers « ft_strcpy »
/tmp/main-559408.o:/home/salty/Documents/libasm/main.c:102 : encore plus de références indéfinies suivent vers « ft_strcpy »
/tmp/main-559408.o : Dans la fonction « list_size_test » :
libasm/main.c:176 : référence indéfinie vers « ft_list_size »
/tmp/main-559408.o : Dans la fonction « list_sort_test » :
libasm/main.c:242 : référence indéfinie vers « ft_list_sort »
/tmp/main-559408.o : Dans la fonction « list_push_front_test » :
libasm/main.c:264 : référence indéfinie vers « ft_list_push_front »
/tmp/main-559408.o : Dans la fonction « list_remove_if_test » :
libasm/main.c:287 : référence indéfinie vers « ft_list_remove_if »
/tmp/main-559408.o : Dans la fonction « atoi_base_test » :
libasm/main.c:297 : référence indéfinie vers « ft_atoi_base »
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Makefile:61: recipe for target 'test' failed
make: *** [test] Error 1
And also the dir tree:
./
├── include
│ └── libasm.h
├── libasm.a
├── main.c
├── Makefile
├── objs
│ ├── ft_atoi_base.o
│ ├── ft_list_push_front.o
│ ├── ft_list_remove_if.o
│ ├── ft_list_size.o
│ ├── ft_list_sort.o
│ ├── ft_read.o
│ ├── ft_strcmp.o
│ ├── ft_strcpy.o
│ ├── ft_strdup.o
│ ├── ft_strlen.o
│ └── ft_write.o
└── srcs
├── ft_atoi_base.s
├── ft_list_push_front.s
├── ft_list_remove_if.s
├── ft_list_size.s
├── ft_list_sort.s
├── ft_read.s
├── ft_strcmp.s
├── ft_strcpy.s
├── ft_strdup.s
├── ft_strlen.s
└── ft_write.s
I have a library which until now was just a static library, and I used it as a submodule of my programs.
Now I want to be able to install it and be able to use it both as a static and a shared library.
I installed (apart from the header files) the following files:
$ tree /usr/local/lib/
/usr/local/lib/
├── libalx
│ ├── libalx-base.a
│ ├── libalx-base.so
│ ├── libalx-cv.a
│ ├── libalx-cv.so
│ ├── libalx-gsl.a
│ ├── libalx-gsl.so
│ ├── libalx-ncurses.a
│ ├── libalx-ncurses.so
│ ├── libalx-ocr.a
│ └── libalx-ocr.so
├── pkgconfig
│ ├── libalx-base.pc
│ ├── libalx-cv.pc
│ ├── libalx-gsl.pc
│ ├── libalx-ncurses.pc
│ └── libalx-ocr.pc
The contents of (some of) the pkg-config files are the following:
libalx-base.pc:
Name: libalx-base
Description: The libalx C/C++ library (base module)
URL: https://github.com/alejandro-colomar/libalx
Version: 1~b4
Requires: libbsd-overlay
Requires.private:
prefix=/usr/local/
libdir=${prefix}/lib/
Cflags: -D _GNU_SOURCE -D _POSIX_C_SOURCE=200809L
Libs: -L ${libdir}/libalx/ -l alx-base
libalx-cv.pc:
Name: libalx-cv
Description: The libalx C/C++ library (openCV extension)
URL: https://github.com/alejandro-colomar/libalx
Version: 1~b4
Requires: libalx-gsl
Requires.private: opencv libalx-base
prefix=/usr/local/
libdir=${prefix}/lib/
Cflags: -D _GNU_SOURCE -D _POSIX_C_SOURCE=200809L
Libs: -L ${libdir}/libalx/ -l alx-cv
libalx-gsl.pc:
Name: libalx-gsl
Description: The libalx C/C++ library (GSL extension)
URL: https://github.com/alejandro-colomar/libalx
Version: 1~b4
Requires:
Requires.private: gsl libalx-base
prefix=/usr/local/
libdir=${prefix}/lib/
Cflags: -D _GNU_SOURCE -D _POSIX_C_SOURCE=200809L
Libs: -L ${libdir}/libalx/ -l alx-gsl
I'm using the library in a program that makes use of only two of the modules: base & cv.
I use the following CFLAGS and LIBS (LDFLAGS) in its Makefile:
################################################################################
# cflags
CFLAGS_STD = -std=gnu17
CFLAGS_OPT = -O3
CFLAGS_OPT += -march=native
CFLAGS_OPT += -flto
CFLAGS_W = -Wall
CFLAGS_W += -Wextra
CFLAGS_W += -Wstrict-prototypes
CFLAGS_W += -Werror
CFLAGS_PKG = `pkg-config --cflags opencv`
CFLAGS_PKG += `pkg-config --cflags libalx-cv`
CFLAGS_PKG += `pkg-config --cflags libalx-base`
CFLAGS_D = -D PROG_VERSION=\"$(PROGRAMVERSION)\"
CFLAGS_D += -D INSTALL_SHARE_DIR=\"$(INSTALL_SHARE_DIR)\"
CFLAGS_D += -D INSTALL_VAR_DIR=\"$(INSTALL_VAR_DIR)\"
CFLAGS = $(CFLAGS_STD)
CFLAGS += $(CFLAGS_OPT)
CFLAGS += $(CFLAGS_W)
CFLAGS += $(CFLAGS_PKG)
CFLAGS += $(CFLAGS_D)
export CFLAGS
################################################################################
# libs
LIBS_OPT = -O3
LIBS_OPT += -march=native
LIBS_OPT += -flto
LIBS_OPT += -fuse-linker-plugin
LIBS_PKG = `pkg-config --libs libalx-cv`
LIBS_PKG += `pkg-config --libs libalx-base`
LIBS = $(LIBS_OPT)
LIBS += $(LIBS_PKG)
export LIBS
################################################################################
And I have the following error:
gcc tmp/coins.o tmp/main.o tmp/parse.o -o cv-coins -O3 -march=native -flto -fuse-linker-plugin `pkg-config --libs libalx-cv` `pkg-config --libs libalx-base`
/usr/bin/ld: cannot find /usr/local//lib//libalx/: file format not recognized
collect2: error: ld returned 1 exit status
What is wrong? I assume the problem is in the .pc files, but I tried moving dependencies from requires to requires.private, the other way around, and other things, and none worked. For example, if I move libbsd-overlay to Requires.private, then the linker complains about not finding strnstr.
My test project folder structure looks like:
TOPDIR
├── a
│ └── a.c
├── b
│ └── b.c
├── c
│ └── c.mk
└── makefile
I wrote a test makefile:
MAKE_DIR = $(PWD)
MODULES := a b c
SRC_DIR := $(addprefix ${MAKE_DIR}/,$(MODULES))
BUILD_DIR := $(addprefix ${MAKE_DIR}/build/,$(MODULES))
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c))
OBJ := $(patsubst ${SRC_DIR}/%.c,${BUILD_DIR}/%.o,$(SRC))
INCLUDES := $(addprefix -I,$(SRC_DIR))
vpath %.c $(SRC_DIR)
default:
#echo "SRC DIR: ${SRC_DIR}"
#echo "Build DIR: ${BUILD_DIR}"
#echo "Source: ${SRC}"
#echo "Obj: ${OBJ}"
#echo "Includes: ${INCLUDES}"
and it output:
[GNU-GCC]howchen#linux:~/Work/c/c/test/test_make
-> make
SRC DIR: /home/howchen/Work/c/c/test/test_make/a /home/howchen/Work/c/c/test/test_make/b /home/howchen/Work/c/c/test/test_make/c
Build DIR: /home/howchen/Work/c/c/test/test_make/build/a /home/howchen/Work/c/c/test/test_make/build/b /home/howchen/Work/c/c/test/test_make/build/c
Source: /home/howchen/Work/c/c/test/test_make/a/a.c /home/howchen/Work/c/c/test/test_make/b/b.c /home/howchen/Work/c/c/test/test_make/c/c.c
Obj: /home/howchen/Work/c/c/test/test_make/a/a.c /home/howchen/Work/c/c/test/test_make/b/b.c /home/howchen/Work/c/c/test/test_make/c/c.c
Includes: -I/home/howchen/Work/c/c/test/test_make/a -I/home/howchen/Work/c/c/test/test_make/b -I/home/howchen/Work/c/c/test/test_make/c
The ${Obj} variables are NOT on *.o format, why? any problem in my makefile?
UPDATE
regarding Magnus Reftel's help, I first try:
OBJ := $(foreach sdir,$(SRC_DIR),$(patsubst $(sdir)/%.c,$(BUILD_DIR)/%.o,$(filter $(sdir)/%.c,$(SRC))))
and it output like:
Obj:
/home/howchen/Work/c/c/test/test_make/build/a
/home/howchen/Work/c/c/test/test_make/build/b
/home/howchen/Work/c/c/test/test_make/build/c/a.o
/home/howchen/Work/c/c/test/test_make/build/a
/home/howchen/Work/c/c/test/test_make/build/b
/home/howchen/Work/c/c/test/test_make/build/c/b.o
/home/howchen/Work/c/c/test/test_make/build/a
/home/howchen/Work/c/c/test/test_make/build/b
/home/howchen/Work/c/c/test/test_make/build/c/c.o
The output contain both PATH and PATH/*.c these two things, seems still NOT correct because ALL obj files go to folder c ONLY
I think I already got the source file list, which stored in $(SRC), therefore I try:
OBJ := $(patsubst %.c,%.o, $(SRC))
and it output:
Obj: /home/howchen/Work/c/c/test/test_make/a/a.o /home/howchen/Work/c/c/test/test_make/b/b.o /home/howchen/Work/c/c/test/test_make/c/c.o
which seems correct, but not because I need locate the output obj file in my build folder not source folder.
If my first try statement is not correct, where is the problem?
If second way can be improved? which way to get $(OBJ) is best for my case?
Because SRC_DIR holds a list of directories, not just one. The pattern you're matching is therefore /home/howchen/Work/c/c/test/test_make/a /home/howchen/Work/c/c/test/test_make/b /home/howchen/Work/c/c/test/test_make/c/%.c which is surely not what you want. Try combining patsubst with the foreach function. Something along the lines of
OBJ := $(foreach dir,$(SRC_DIR),$(patsubst $(dir)/%.c,getting/the/correct/build/dir/here/is/left/as/an/excercise/to/the/reader%.o,$(filter $(dir)/%,$(SRC))))
I have a project that has many makefiles inside it. Because sometimes I need to compile only some parts of my project so I decided to have one makefile in each directory. But when I want to run the main makefile that includes all other ones to compile my project it gives me lots of errors.
This is my project tree:
root 'makefile'
-folder1 'foo1.c foo2.c makefile'
-folder2 'makefile'
--folder2-1 'foo3.c foo4.c makefile'
--folder2-2 'foo5.c makefile'
Each makefile in the very last directory has been included to it's upper makefile. But it doesn't run the main makefile. I'm really new to GNU make and I want to have something like this but I don't know how. I just wrote some make scripts but it doesn't work.
I just want to have something that I can compile the projects parts separately or compile the whole project using multiple makefiles.
any way, I show you something and hope can help you:
all:
#$(MAKE) -C subfolder
or if you want to use *.mk as your sub makefile, you can write:
all:
#$(MAKE) -C busfolder -f somename.mk
I show you my example, my DIR looks like:
TOPDIR-- Makefile
|
|-- debug
| |-- debug.c
| |-- debug.h
| |-- debug.mk
| |-- instrument.c
| `-- uart_print.c
|-- driver
| |-- driver.c
| |-- driver_ddi.c
| |-- driver_ddi.h
| |-- driver.h
| `-- driver.mk
|-- include
| `-- common.h
|-- Makefile
|-- mw
| |-- manager.c
| `-- mw.mk
|-- root
| |-- main.c
| `-- root.mk
and my TOP makefile looks like:
MAKE_DIR = $(PWD)
ROOT_DIR := $(MAKE_DIR)/root
DRV_DIR := $(MAKE_DIR)/driver
INCLUDE_DIR := $(MAKE_DIR)/include
DEBUG_DIR := $(MAKE_DIR)/debug
INC_SRCH_PATH :=
INC_SRCH_PATH += -I$(ROOT_DIR)
INC_SRCH_PATH += -I$(DRV_DIR)
INC_SRCH_PATH += -I$(INCLUDE_DIR)
INC_SRCH_PATH += -I$(DEBUG_DIR)
LIB_SRCH_PATH :=
LIB_SRCH_PATH += -L$(MAKE_DIR)/libs
COLOR_ON = color
COLOR_OFF =
CC = $(COLOR_ON)gcc
#CC = $(COLOR_OFF)gcc
LD = ld
LINT = splint
LIBS := -ldriver -ldebug -lmw -lm -lpthread
CFLAGS :=
CFLAGS += $(INC_SRCH_PATH) $(LIB_SRCH_PATH)
CFLAGS += -Wall -O -ggdb -Wstrict-prototypes -Wno-pointer-sign -finstrument-functions -fdump-rtl-expand
CFLAGS += -DDEBUG -D_REENTRANT
LDFLAGS :=
export MAKE_DIR CC LD CFLAGS LDFLAGS LIBS LINT INC_SRCH_PATH
all:
#$(MAKE) -C debug -f debug.mk
#$(MAKE) -C driver -f driver.mk
#$(MAKE) -C mw -f mw.mk
#$(MAKE) -C root -f root.mk
.PHONY: clean
clean:
#$(MAKE) -C debug -f debug.mk clean
#$(MAKE) -C driver -f driver.mk clean
#$(MAKE) -C mw -f mw.mk clean
#$(MAKE) -C root -f root.mk clean
it will call sub DIR *.mk during the compile. The sub DIR makefile, I just write a simple example for you reference:
LIB = $(MAKE_DIR)/libs/yourmodulename.a
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c, %.o, $(SRCS))
$(LIB): $(OBJS)
#mkdir -p ../libs
#$(AR) cr $# $^
#echo " Archive $(notdir $#)"
$(OBJS): $(SRCS)
#$(CC) $(CFLAGS) -c $^
#echo " CC $(OBJS)"
.PHONY: clean
clean:
#$(RM) -f $(LIB) $(OBJS)
#$(RM) -f *.expand
#echo " Remove Objects: $(OBJS)"
for the makefile, which generate the final target file(like a.out) is little bit different, because I use the sub makefile to generate LIB file, and I use a root.mk to generate final target:
PROG = ../prog/DEMO
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c, %.o, $(SRCS))
$(PROG): $(SRCS)
#mkdir -p ../prog
#$(CC) $^ $(CFLAGS) -Wl,-Map=$(PROG).map $(LIBS) -o $#
#echo " Generate Program $(notdir $(PROG)) from $^"
.PHONY: clean
clean:
#$(RM) -f $(OBJS) $(PROG)
#$(RM) -f *.expand
#$(RM) -rf ../prog ../libs
#echo " Remove Objects: $(OBJS)"
#echo " Remove Libraries: $(notdir $(PROG))"