Makefile:递归编译 C++ 文件
Makefile: Compile C++ Files recursively
我是 makefile 的新手,曾尝试阅读互联网上的资源来解决我的问题,但我找不到解决方案。
基本上我正在处理一个包含 C++ 和 Cuda 文件的项目。因为我喜欢让我的东西结构化,所以我通常使用这样的嵌套文件夹结构:
|- bin
|- build
| |- cc
| |- cu
|- src
|- makefile
|- main.cpp
我当前的 Makefile 如下所示:
CC = g++
NVCC = nvcc
CC_SRC = $(wildcard *.cpp */*.cpp */*/*.cpp */*/*/*.cpp)
CU_SRC = $(wildcard *.cu */*.cu */*/*.cu */*/*/*.cu)
CC_LIBS = -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
ROOT = ./
FOLDER = $(ROOT)bin/
OBJECTS = $(ROOT)build/
CC_OBJ = $(OBJECTS)cc/
CU_OBJ = $(OBJECTS)cu/
NAME = Test
EXE = $(ROOT)$(FOLDER)$(NAME)
NVCC_FLAGS =
CC_FLAGS =
## Compile ##
run:build
build: $(EXE)
$(CC_SRC):
@echo compiling
$(CC) $(CC_FLAGS) -c $< -o $a
$(EXE) : $(CC_SRC)
@echo test 123
最初我想将所有 C++
文件编译成 build/cc
文件。同样,我的 .cu
文件应该编译到 build/cu
文件夹中。
最初我制作了一个通配符来捕获所有 c++
文件:
CC_SRC = $(wildcard *.cpp */*.cpp */*/*.cpp */*/*/*.cpp)
CU_SRC = $(wildcard *.cu */*.cu */*/*.cu */*/*/*.cu)
但由于某种原因,相应的规则没有被执行。如果有人能在这里帮助我,我很高兴。
问候
芬恩
这条规则没有意义:
$(CC_SRC):
@echo compiling
$(CC) $(CC_FLAGS) -c $< -o $a
(我假设你在这里指的是 $@
而不是 $a
)。该规则表示创建每个源文件的方法是编译它们。但是,make 不需要构建源文件:它们已经存在。所以它永远不会调用你的规则。
您需要将目标设为要创建 的文件,而不是已经存在的文件。您要创建的文件是目标文件,而不是源文件。那么前提是文件已经存在。因此,对于编译,您需要一个模式规则,如下所示:
$(CC_OBJ)%.o : %.cpp
@echo compiling
@mkdir -p $(@D)
$(CC) $(CC_FLAGS) -c $< -o $@
那么你希望你的目标依赖于目标文件,而不是源文件,就像这样:
$(EXE) : $(CC_SRC:%.cpp=$(CC_OBJ)%.o)
@echo test 123
我建议将您的项目迁移到 CMake (https://cmake.org/cmake/help/latest/),特别是如果您的项目还不是太大的话。
Makefile 真的很痛苦; CMake 可以大大简化问题。
我是 makefile 的新手,曾尝试阅读互联网上的资源来解决我的问题,但我找不到解决方案。
基本上我正在处理一个包含 C++ 和 Cuda 文件的项目。因为我喜欢让我的东西结构化,所以我通常使用这样的嵌套文件夹结构:
|- bin
|- build
| |- cc
| |- cu
|- src
|- makefile
|- main.cpp
我当前的 Makefile 如下所示:
CC = g++
NVCC = nvcc
CC_SRC = $(wildcard *.cpp */*.cpp */*/*.cpp */*/*/*.cpp)
CU_SRC = $(wildcard *.cu */*.cu */*/*.cu */*/*/*.cu)
CC_LIBS = -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
ROOT = ./
FOLDER = $(ROOT)bin/
OBJECTS = $(ROOT)build/
CC_OBJ = $(OBJECTS)cc/
CU_OBJ = $(OBJECTS)cu/
NAME = Test
EXE = $(ROOT)$(FOLDER)$(NAME)
NVCC_FLAGS =
CC_FLAGS =
## Compile ##
run:build
build: $(EXE)
$(CC_SRC):
@echo compiling
$(CC) $(CC_FLAGS) -c $< -o $a
$(EXE) : $(CC_SRC)
@echo test 123
最初我想将所有 C++
文件编译成 build/cc
文件。同样,我的 .cu
文件应该编译到 build/cu
文件夹中。
最初我制作了一个通配符来捕获所有 c++
文件:
CC_SRC = $(wildcard *.cpp */*.cpp */*/*.cpp */*/*/*.cpp)
CU_SRC = $(wildcard *.cu */*.cu */*/*.cu */*/*/*.cu)
但由于某种原因,相应的规则没有被执行。如果有人能在这里帮助我,我很高兴。
问候 芬恩
这条规则没有意义:
$(CC_SRC):
@echo compiling
$(CC) $(CC_FLAGS) -c $< -o $a
(我假设你在这里指的是 $@
而不是 $a
)。该规则表示创建每个源文件的方法是编译它们。但是,make 不需要构建源文件:它们已经存在。所以它永远不会调用你的规则。
您需要将目标设为要创建 的文件,而不是已经存在的文件。您要创建的文件是目标文件,而不是源文件。那么前提是文件已经存在。因此,对于编译,您需要一个模式规则,如下所示:
$(CC_OBJ)%.o : %.cpp
@echo compiling
@mkdir -p $(@D)
$(CC) $(CC_FLAGS) -c $< -o $@
那么你希望你的目标依赖于目标文件,而不是源文件,就像这样:
$(EXE) : $(CC_SRC:%.cpp=$(CC_OBJ)%.o)
@echo test 123
我建议将您的项目迁移到 CMake (https://cmake.org/cmake/help/latest/),特别是如果您的项目还不是太大的话。
Makefile 真的很痛苦; CMake 可以大大简化问题。