我在主src目录下的不同子文件夹中有.c文件,我遇到运行Makefile的问题,我是Makefile的新手,需要动手Makefile才能工作并创建一个静态库。
src / math / addition / add.c (+ add.h)
int add(int a, int b) {return a + b;}
src / math / subtraction / sub.c (+ sub.h)
int sub(int a, int b) {return a - b;}
的src /数学/ math.c
#include "addition/add.h"
#include "subtraction/sub.h"
Makefile (在项目的根目录)
SRC=src/math/Math.c src/math/Math.h src/math/addition/add.c src/math/addition/add.h src/math/subtraction/sub.c src/math/subtraction/sub.h
INCLUDE_PATH=src/
Math: bin
ar rcs libMath.a Math.o
bin:
mkdir bin/
for dir in $(SRC); do \
cd $$dir; \
gcc -c *.c -I../; \
mv *.o ../../../bin; \
cd -; \
done
如果您认为有更好的方式或任何横向思维,我并不关注任何事情。
答案 0 :(得分:0)
Makefile擅长两件事:构建依赖图并在依赖图中的每个节点之间执行步骤。
如果您可以访问GNUMake(我们大多数人都这样做;它几乎是任何人使用的),您可以使用VPATH
来整理一下。 VPATH
用于告诉make它可以在哪里找到源文件。如果在不同目录下有多个具有相同名称的文件,请小心。
我建议您使用类似于以下内容的内容
VPATH := src src/math src/math/addition src/math/subtraction
CFLAGS += -Isrc -Isrc/math -Isrc/mathaddition -Isrc/math/subtraction
all: libMath
libMath: bin/Math.o bin/add.o bin/sub.o
ar rcs libMath bin/Math.o bin/add.o bin/sub.o
bin/%.o: %.c %.h
Make包含默认的.c - > .o你可以使用的规则; %.o: %.c %.h
执行此操作,但也声明所有.o
个文件,默认情况下 ,取决于.c
和.h
文件前缀(%
部分)作为目标文件。
我怀疑您的Math.o
目标还取决于addition.h
和subtraction.h
个文件;您可以使用规则Math.o
声明Math.o: Math.c Math.h addition.h subtraction.h
依赖于这些文件。
请记住使用标签替换ar之前的空格。
您可能希望更改源文件和/或头文件的组织方式。
通常ar
会生成以.a
结尾的存档文件。您可能也希望改变它。
如果你使用make,你可以使用并行构建(make -J
)来真正加快编译时间;如果你使用它错了,一切都会变慢,我们会有另一个人开始讨厌制作,因为他们不理解。
答案 1 :(得分:0)
生成文件:
#
# Boilerplate.
#
all:
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,\
TYPE := $(firstword $($1.TYPE) binary),\
))
$(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_binary = $(CC) $($(target).LDFLAGS) -o $@ $^
add_target.link_lib = $(AR) rcs $@ $^
add_target.link = $(add_target.link_$($(target).TYPE))
# Compile command line
add_target.compile = $(CC) -c -o $@ $($(target).CFLAGS) $<
# -- Directories --
SRC_ROOT := ./src
BIN := ./bin
# Add 'math' target to the project
$(eval $(call add_target,math,\
TYPE := lib,\
TARGET := $(BIN)/math.a,\
SOURCES += ${SRC_ROOT}/math/addition/add.c\
${SRC_ROOT}/math/subtraction/sub.c\
${SRC_ROOT}/math/math.c,\
CFLAGS := -Wall -I./$(SRC_ROOT)/math,\
))
all: ${PHONY_TARGETS}
.PHONY: all
clean: | $(CLEAN_TARGETS)
.PHONY: clean
目录结构:
$ find
.
./Makefile
./src
./src/math
./src/math/addition
./src/math/addition/add.c
./src/math/addition/add.h
./src/math/math.c
./src/math/subtraction
./src/math/subtraction/sub.c
./src/math/subtraction/sub.h
文件内容:
$ find src/ -type f -exec sh -c "echo Contents of {} file:; cat {}; echo" \;
Contents of src/math/addition/add.c file:
int add(int a, int b) {return a + b;}
Contents of src/math/addition/add.h file:
int add(int a, int b);
Contents of src/math/math.c file:
#include "addition/add.h"
#include "subtraction/sub.h"
Contents of src/math/subtraction/sub.c file:
int add(int a, int b) {return a - b;}
Contents of src/math/subtraction/sub.h file:
int add(int a, int b);
运行Makefile:
$ make
add_target(math)
math.TYPE := lib
math.TARGET := ./bin/math.a
math.SOURCES += ./src/math/addition/add.c ./src/math/subtraction/sub.c ./src/math/math.c
math.CFLAGS := -Wall -I././src/math
math.OBJDIR := ./objs/math
math.TYPE := lib
math.objs := ./objs/math/add.o ./objs/math/sub.o ./objs/math/math.o
end
mkdir -p objs/math && cc -c -o objs/math/add.o -Wall -I././src/math src/math/addition/add.c
cc -c -o objs/math/sub.o -Wall -I././src/math src/math/subtraction/sub.c
cc -c -o objs/math/math.o -Wall -I././src/math src/math/math.c
mkdir -p bin && ar rcs bin/math.a objs/math/add.o objs/math/sub.o objs/math/math.o
这个通用的makefile缺少一些重要的功能,比如跟踪.h文件依赖项,链接静态/动态库等等。用你自己需要的功能扩展它。