如何在生成文件中动态重命名目标文件

Posted

技术标签:

【中文标题】如何在生成文件中动态重命名目标文件【英文标题】:How to dynamically rename an object file in a makefile 【发布时间】:2011-04-25 14:32:28 【问题描述】:

我对 makefile 非常陌生。我之前做过的最复杂的任务是在已经设计好的 makefile 中包含新的 .h 和 .cpp 或 .c。

我必须将项目的编译过程从 Visual Studio 移植到 gcc,一位同事已经为此编写了一个解决方案,但他使用 4 个 bash 脚本和一个 makefile 来编译解决方案。

我没有这样做,而是在寻找更易于维护的解决方案。我承认我的问题可能很愚蠢,但我在任何地方都找不到,也无法完全理解。

在下面的目标中:

$(OBJECTS): %.o: %.cpp 
    $(CC) $(CPPFLAGS) -c $< -o $@

我想测试正在创建的 .o 是否已经存在并将其重命名为其他名称。这是必要的,因为在项目中存在多个同名但内容不同的源文件。

例如,如果当前正在编译的 .cpp 被称为 file.cpp 并且将生成的对象是 file.o,则规则应该测试 file.o 是否已经存在并将当前 file.o 重命名为其他名称.

如果您知道任何解释这一点的好教程,请告诉我。我发现了很多示例,这些示例展示了如何为当前正在按该规则编译的文件进行测试,但没有一个示例会重命名对象 .o。

在此先感谢您对此处所写的任何“愚蠢”表示歉意。 :-)

【问题讨论】:

我过去所做的是将目标文件放在与源文件相同的目录层次结构中。我猜你有不同级别的同名文件? @Max ,是的。有两个不同的目录,源文件名为 file1.cpp file2.cpp 等。 【参考方案1】:

首先,我们深表同情。

Make 并不是真正为处理这种歧义而设计的,所以我们必须使用一个 kludge。您还没有说要将文件重命名为什么,所以现在假设我们将file.o 移动到file_save.o

# This tells Make that these are not real targets, so that it will
# proceed even if file.o already exists.
.PHONY: $(OBJECTS)

$(OBJECTS): %.o: %.cpp 
    # If file.o exists, move it to file_save.o
    @if [ -f $@ ]; then mv $@ $*_save.o; fi
    $(CC) $(CPPFLAGS) -c $< -o $@

【讨论】:

嘿,非常感谢。此代码似乎有效,但是没有生成 *_save.o 文件。我认为这是因为我的源 cpp 文件是在变量 SOURCE = file1.cpp file2.cpp file1.cpp 中定义的,然后我使用 OBJECTS = $(SOURCES:.cpp=.o) 创建了 OBJECTS 规则。 真的吗?没关系...用这个替换if 行,看看会发生什么:mv $@ $*_save.o。当没有file.o 可以移动时,它会第一次抱怨,否则它会做同样的事情并告诉你它在做什么。 感谢您的帮助!当我尝试它时,make 在第一个 .o not found 之后立即中止编译。 @xlogdan:哎呀!对不起,我应该说-mv $@ $*_save.o。一开始只尝试一个file.o,而不是整个OBJECTS列表。 @Beta ,非常感谢您的帮助!它仍然没有显示任何效果,抱怨我在同一规则中包含了两个相等的目标并且它不会执行上面的命令,因为没有.o。无论如何,我为这整个混乱道歉,但我让它在批处理文件中编译具有相同名称的源代码,我只是指定每个文件将有一个不同的 .o 名称。接下来我调用makefile,它将所有东西捆绑在一个静态库中。我没有更多的时间在这方面,所以很遗憾我将不得不让它保持原样,至少我将它从 5 个 bash 脚本减少到 1 个加上一个 make 文件。【参考方案2】:

扩展我对这个问题的评论:

也许您应该考虑将目标文件放在与源文件相同的目录层次结构中,以防止命名冲突。

这样src/network/client.cpp就被编译成build/obj/network/client.o了。

我对 makefile 非常生疏,但我相信我通过执行以下操作解决了这个问题:

$SRC= src/network/client.cpp src/main.cpp .....
$OBJ= makefile_replace_function($SRC, .o)

$(OBJ) : $(SRC)
   compile_instructions

你必须将 makefile_replace_functioncompile_instructions 替换为他们真正的等价物,因为那时我已经忘记了......

我意识到这可能不是很有帮助,但至少它是一个值得考虑的想法。

【讨论】:

以上是关于如何在生成文件中动态重命名目标文件的主要内容,如果未能解决你的问题,请参考以下文章

在linux下复制文件到另外一个目录并且重命名的具体操作如何?

如何在 CMake 中安装时使用版本号重命名/修改目标文件?

如果目标文件不存在,则在 Node.js 中异步重命名文件

mv命令(移动和重命名)

word文档在重命名时提示:源文件名和目标文件名相同。不能重命名,这是怎么回事。

文件重命名