带有目标文件目录的Makefile

时间:2018-07-26 14:47:25

标签: makefile

我对项目具有以下结构,并且我刚刚开始引入Makefile来构建软件:

├── Makefile
├── README.md
├── cg
│   └── cg.c
└── utilities
   ├── utilities.c
   └── utilities.h

我试图将目标文件放在obj目录中,但似乎无法正常工作。

我的makefile看起来像:

CC=mpicc
CFLAGS=-O3 -std=c99
LIBS=
MKDIR_P = mkdir -p

make_build_dir:
    @mkdir -p obj/

utilities.o: utilities/utilities.c
    $(CC) $(CFLAGS) -o ./obj/$@ -c $<

cg.o: cg/cg.c
    $(CC) $(CFLAGS) -o ./obj/$@ -c $<

.PHONY: make_build_dir

cg.exe: make_build_dir utilities.o cg.o 
    $(CC) $(CFLAGS) -o $@ $<

clean:
    rm -fr obj
    rm cg.exe

但是这会产生以下错误:

a@a:b/b ‹master*›$ make cg.exe
mpicc -O3 -std=c99 -o ./obj/utilities.o -c utilities/utilities.c
mpicc -O3 -std=c99 -o ./obj/cg.o -c cg/cg.c
cg/cg.c:133:3: warning: implicit declaration of function 'decompose' is invalid in C99
      [-Wimplicit-function-declaration]
  decompose(num_chunks, chunks_per_rank,me, &settings); 
  ^
1 warning generated.
mpicc -O3 -std=c99 -o cg.exe make_build_dir
clang: error: no such file or directory: 'make_build_dir'
make: *** [cg.exe] Error 1

如何获取它以在obj目录中生成目标文件,然后在顶级目录中生成可执行文件?

2 个答案:

答案 0 :(得分:1)

makefile的此链接部分

cg.exe: make_build_dir utilities.o cg.o 
    $(CC) $(CFLAGS) -o $@ $<

有两个问题。首先,$<指目标cg.exe的第一个先决条件,即make_build_dir。在这里将其声明为.PHONY并没有帮助,只是将其传递给$(CC)。其次,utilities.o cg.o都不在此位置。您可以将规则更改为

cg.exe: obj/utilities.o obj/cg.o 
    $(CC) $(CFLAGS) -o $@ $^

请注意自动变量$^,它涉及所有先决条件。此外,目标文件目标应为

obj/cg.o: cg/cg.c
    $(CC) $(CFLAGS) -o $@ -c $<

(与utilities.o相同)。

答案 1 :(得分:0)

首先,您需要make_build_dir才能放置任何*.omake的地方。

您可以使Makefile更通用。

.PHONY: all clean info
.DEFAULT_GOAL := all

SRC_DIRS = cg utilities
OBJ_DIR  = obj
EXE      = cg.exe

SOURCES = $(foreach path, $(SRC_DIRS), $(wildcard $(path)/*.c))
OBJECTS = $(addprefix $(OBJ_DIR)/, $(notdir $(SOURCES:%.c=%.o)))

$(OBJ_DIR)/%.o: */%.c
    $(CC) $(CFLAGS) -o $@ -c $<

all: make_build_dir $(EXE)

info:
    $(info SOURCES=$(SOURCES))
    $(info OBJECTS=$(OBJECTS))

make_build_dir:
    @mkdir -p $(OBJ_DIR)

$(EXE): $(OBJECTS)
    $(CC) $(CFLAGS) -o $@ $^

使用此Makefile,您可以向SRC_DIRS添加更多源目录,它将自动在其中编译源。

它有什么作用?使用make选项运行-n,以查看:

$ make -n
mkdir -p obj
cc  -o obj/cg.o -c cg/cg.c
cc  -o obj/utilities.o -c utilities/utilities.c
cc  -o cg.exe obj/cg.o obj/utilities.o

您还可以通过以下方式显示有关变量的信息:

$ make info
SOURCES= cg/cg.c  utilities/utilities.c
OBJECTS=obj/cg.o obj/utilities.o