Makefile路径问题

时间:2018-01-23 08:55:32

标签: c makefile

我在主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

如果您认为有更好的方式或任何横向思维,我并不关注任何事情。

2 个答案:

答案 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.hsubtraction.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文件依赖项,链接静态/动态库等等。用你自己需要的功能扩展它。