修改Makefile中的文件名

修改Makefile中的文件名

由于这里不重要的原因,我有一个源代码,我会自动逐个文件地处理源代码,并以系统的方式重命名处理后的源文件。例如,我从名为的文件开始

fun1.c fun2.c

并最终得到文件

fun1_a.c fun2_a.c

我也希望 Makefile 能够自动调整。 Makefile 的基本版本是

SRC=    fun1.c fun2.c

%.o: $.c
        $(CC) $(CFLAGS) -c $< -o $@

OBJ= $(SRC:.c=.o)

fun2.o: fun1.o

如何最好地处理文件,以便根据需要更改源文件和依赖项定义中的每个条目,但模式规则保持不变?换句话说,我需要的是:

SRC=    fun1_a.c fun2_a.c

%.o: $.c
        $(CC) $(CFLAGS) -c $< -o $@

OBJ= $(SRC:.c=.o)

fun2_a.o: fun1_a.o

我认为这是微不足道的,但我的脚本编写能力,尤其是sedperl是有限的。

编辑:请注意,在实践中,并非所有文件都会被调用,funx.c其中x是整数,因此我正在寻找一种适用于任何文件名的解决方案。

答案1

我建议创建整个源代码树的副本,然后修改副本目录中的文件而不重命名它们。这样你就不需要修改makefile。作为奖励,您只需通过比较目录即可了解更改的概述。

而不是这个

project
  fun1.c
  fun1_mod.c
  fun2.c
  fun2_mod.c
  Makefile
  Makefile_mod

你有这个

project
  fun1.c
  fun2.c
  Makefile
project_mod
  fun1.c
  fun2.c
  Makefile

阐述

如果 makefile 非常简单,就像您的示例一样,您可能可以使用 sed 修改 makefile 中的文件名。但 makefile 是神秘的野兽。具有大量隐式规则和多级变量扩展。

即使在简单的 makefile 中,修改文件名也是很常见的情况。甚至你的 makefile 也有一些文件名修改 ( OBJ= $(SRC:.c=.o))。这如果使用 sed 更改某些内容,会得到意想不到的结果。

像这样的常见通配符*.c很容易最终收集比预期更多的文件。尝试编写通配符来排除或包含后缀就像放牧猫一样。

如果原始源文件和修改后的源文件位于同一目录中,您永远无法确定原始源文件是否是由修改后的 makefile 无意中编译的,反之亦然。

而且,我预感到,你不会只有一项修改。你会有很多。所以不仅仅是fun1_mod.cfun2_mod.c但是”_mod1 _mod2 _mod3 _mod3butpartmod1等等。

您将永远头痛于弄清楚哪个二进制文件是从哪个 modset 编译出来的。

因此,为每次修改创建整个源代码树的副本。修改各个目录下的源码。保持文件名相同。保持 makefile 相同。

这样你就进入一个目录并编译。转到其他目录并编译。总是相同的 makefile。并且始终确定将编译哪些文件。 (除非 makefile 从父目录和同级目录中获取源文件,但这不是常见的做法,并且在 makefile 社区中是不受欢迎的。)

奖金:

您可以使用您喜欢的目录比较工具轻松查看一个 modset 与另一个 modset 之间的区别。

您可以将修改保留在源代码管理中,例如 git。每个模组一个分支。您可以在主分支中进行更改并将其传播到其他分支。你可以挑选周围的变化。你可以向同事推拉。

答案2

假设原始文件名是静态的,只有重命名操作的结果是不可预测的。重命名文件时,会生成一个附加文件,其中包含原始文件名到新名称的映射,例如:

fun1.c=fun1_a.c
fun2.c=fun2_a.c

假设生成的映射文件名为rename.mk,可以Makefile通过以下方式修改:

include rename.mk
SRC=    $(fun1.c) $(fun2.c)

%.o: $.c
        $(CC) $(CFLAGS) -c $< -o $@

OBJ= $(SRC:.c=.o)

$(fun2.c:.c=.o): $(fun1.c:.c=.o)

文件名已成为变量名,并用于通过rename.mk.

相关内容