使用 Gnu Make 实用程序自动创建具有与源代码不同的构建结构的文件

发布于 2024-11-27 00:50:33 字数 804 浏览 1 评论 0原文

我见过以下技术用于自动编译特定目录中的所有 C(或 C++,或者我想您想要的任何扩展名)文件。

SOURCE_DIRS = .
SOURCES := $(subst ./,,$(wildcard $(SOURCE_DIRS:=/*.cpp)))
HEADERS := $(subst ./,,$(wildcard $(SOURCE_DIRS:=/*.h)))
OBJECTS := $(addprefix build/,$(SOURCES:.cpp=.o))
CXX = g++
CXXFLAGS = -Wall -pedantic -g
#LDFLAGS = 

all: build/exe_name

build/exe_name: $(OBJECTS)
        $(CXX) -o $@ $(OBJECTS) $(LDFLAGS)

build/%.o: %.cpp $(HEADERS) Makefile
        mkdir -p $(dir $@)
        $(CXX) -o $@ $(CXXFLAGS) -c $<

唯一的问题是它以与源目录中相同的结构构建所有文件。因此,如果您有一个包含代码的子文件夹,那么构建将有一个匹配的子文件夹。

那么,我如何修改它(或者还能做什么),以使所有输出的目标直接放置在 build/ 目录中,而不是放置在与源目录匹配的层次结构中?

我考虑过尝试删除在目标中使用“%”时可能出现的任何目录,但我找不到任何好的命令来做到这一点。另外,尝试在创建时更改 OBJECTS 路径似乎有点问题,因为我不知道“%”变量如何读取它,除了它神奇地编译 OBJECTS 列表中的所有内容之外。

感谢您提供的任何帮助。

I've seen the following technique used to automatically compile all of the C (or C++, or I suppose whatever extension you wanted) files in a particular directory.

SOURCE_DIRS = .
SOURCES := $(subst ./,,$(wildcard $(SOURCE_DIRS:=/*.cpp)))
HEADERS := $(subst ./,,$(wildcard $(SOURCE_DIRS:=/*.h)))
OBJECTS := $(addprefix build/,$(SOURCES:.cpp=.o))
CXX = g++
CXXFLAGS = -Wall -pedantic -g
#LDFLAGS = 

all: build/exe_name

build/exe_name: $(OBJECTS)
        $(CXX) -o $@ $(OBJECTS) $(LDFLAGS)

build/%.o: %.cpp $(HEADERS) Makefile
        mkdir -p $(dir $@)
        $(CXX) -o $@ $(CXXFLAGS) -c 
lt;

The only problem is that it builds all of the files in the same structure as is in the source directory. So if you had a sub folder with code in it, than the build would have a matching sub folder.

So, how can I modify this (or what else can be done), to get all of the outputted targets to be placed directly in the build/ directory, rather than in a hierarchy that matches the source directory?

I've thought about trying to strip any directories that may be presented in the '%' when it's used in the target, but I can't find any good commands to do that. Also, it seems a bit problematic to try to change the OBJECTS path when created, as I have no idea how the '%' variable reads it, other than that it is magically compiling everything in the OBJECTS list.

Thank you for any help you can give.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

云淡风轻 2024-12-04 00:50:33

按照顺序,

  1. 我不明白这是如何工作的。您的通配符方法不会递归到源文件夹的子文件夹,并且您的 %.o 规则在除“SOURCE_DIRS=.”之外的任何情况下都不起作用。
  2. 你的 %.o 规则有点松散。如果您更改一个标头,Make将重建所有目标文件。
  3. 所有可以找到的源代码合并到可执行文件中可能并不明智。在这一方案中,很难有多个具有共享代码的可执行文件。
  4. 为了克服 1) 的问题并编写一个我可以测试的 makefile,我将不得不搞乱“find”,这是我讨厌的,所以以下内容未经测试。
  5. 我认为这可以做到(在 GNUMake 中):
SOURCES := whatever...
vpath %.cpp $(dir $(SOURCES))
SOURCES := $(notdir $(SOURCES))

In order,

  1. I don't see how this can work as it is. Your wildcard method will not recurse into subfolders of the source folder, and your %.o rule will not work in any case other than `SOURCE_DIRS=.`.
  2. Your %.o rule is kind of loose. If you change one header, Make will rebuild all object files.
  3. Incorporating every source that can be found into your executable is probably not wise. In this scheme it is difficult to have more than one executable with shared code.
  4. To overcome the problems of 1) and write a makefile I could test, I would have to mess with "find", which I hate, so the following is untested.
  5. I think this will do it (in GNUMake):
SOURCES := whatever...
vpath %.cpp $(dir $(SOURCES))
SOURCES := $(notdir $(SOURCES))
萤火眠眠 2024-12-04 00:50:33

最简单的(尽管不是严格意义上的 make-only)方法是使用 automake 并且不设置 subdir-options 选项。

The easiest (although not strictly make-only) way would be to use automake and not set the subdir-options option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文