首页 > 解决方案 > Makefile:创建构建目录

问题描述

我有一个 C++ 项目,其源文件跨越许多目录,并且在标头中具有相互依赖性(一个目录的标头包括来自其他目录源的标头)。

我有一个看起来像这样的makefile:

CXX = g++
CFLAGS = -Wall -std=c++17
SRC = *.cpp ./num_utils/*.cpp ./shapes/*.cpp ./data_utils/*.cpp
all: $(SRC)
    $(CXX)  $(CFLAGS)  $(SRC)  -o main $(LDFLAGS)

我想创建一个文件获取输出的build目录.o,并修改它,makefile以便我不会在每次调用时重新编译每个文件make

我对阅读文档感到困惑,请帮助或指向一个适合初学者的教程

标签: c++makefile

解决方案


makefile可能仅专用于 gnu-make(因为wildcard, patsubst,dir内置命令和ifeq)在 unix 环境中(因为mkdir -p, rm -rf)。

它在build目录下重新创建与源文件相同的目录层次结构。

根据评论中的进一步问题,添加了在调试构建(opt=0默认情况下)和发布构建(opt=1在命令行上)之间进行选择的能力。

opt=0

CXX=g++
CFLAGS=-Wall -std=c++17
SRC=${wildcard *.cpp ./num_utils/*.cpp ./shapes/*.cpp ./data_utils/*.cpp}
OBJ=${patsubst %.cpp,build/%.o,${SRC}}

ifeq (${opt},0)
  CFLAGS+=-g
else
  CFLAGS+=-O3
endif

all: ${OBJ}
    ${CXX}  ${CFLAGS} ${OBJ} -o main ${LDFLAGS}

build/%.o : %.cpp
    mkdir -p ${dir $@}
    ${CXX} -o $@ $< -c ${CFLAGS}

clean :
    rm -rf main build
$ make clean
rm -rf main build
$ tree
.
├── data_utils
│   ├── f3.cpp
│   └── f33.cpp
├── main.cpp
├── makefile
├── num_utils
│   ├── f1.cpp
│   └── f11.cpp
└── shapes
    ├── f2.cpp
    └── f22.cpp

3 directories, 8 files
$ make 
mkdir -p build/
g++ -o build/main.o main.cpp -c -Wall -std=c++17 -g
mkdir -p build/./num_utils/
g++ -o build/./num_utils/f1.o num_utils/f1.cpp -c -Wall -std=c++17 -g
mkdir -p build/./num_utils/
g++ -o build/./num_utils/f11.o num_utils/f11.cpp -c -Wall -std=c++17 -g
mkdir -p build/./shapes/
g++ -o build/./shapes/f2.o shapes/f2.cpp -c -Wall -std=c++17 -g
mkdir -p build/./shapes/
g++ -o build/./shapes/f22.o shapes/f22.cpp -c -Wall -std=c++17 -g
mkdir -p build/./data_utils/
g++ -o build/./data_utils/f3.o data_utils/f3.cpp -c -Wall -std=c++17 -g
mkdir -p build/./data_utils/
g++ -o build/./data_utils/f33.o data_utils/f33.cpp -c -Wall -std=c++17 -g
g++ -g build/main.o build/./num_utils/f1.o build/./num_utils/f11.o build/./shapes/f2.o build/./shapes/f22.o build/./data_utils/f3.o build/./data_utils/f33.o -o main 
$ make clean
rm -rf main build
$ make opt=1
mkdir -p build/
g++ -o build/main.o main.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./num_utils/
g++ -o build/./num_utils/f1.o num_utils/f1.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./num_utils/
g++ -o build/./num_utils/f11.o num_utils/f11.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./shapes/
g++ -o build/./shapes/f2.o shapes/f2.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./shapes/
g++ -o build/./shapes/f22.o shapes/f22.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./data_utils/
g++ -o build/./data_utils/f3.o data_utils/f3.cpp -c -Wall -std=c++17 -O3
mkdir -p build/./data_utils/
g++ -o build/./data_utils/f33.o data_utils/f33.cpp -c -Wall -std=c++17 -O3
g++ -Wall -std=c++17 -O3 build/main.o build/./num_utils/f1.o build/./num_utils/f11.o build/./shapes/f2.o build/./shapes/f22.o build/./data_utils/f3.o build/./data_utils/f33.o -o main 
$ ./main 
in main()
in f1()
in f2()
in f3()
in f11()
in f22()
in f33()
$ make --version
GNU Make 4.3
Built for x86_64-pc-linux-gnu
...

推荐阅读