我对项目具有以下结构,并且我刚刚开始引入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目录中生成目标文件,然后在顶级目录中生成可执行文件?
答案 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
才能放置任何*.o
或make
的地方。
您可以使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