配置更改时如何节省构建时间?

How to save build time when the configuration change?

考虑一个包含数百个 C 文件的项目,这些文件可以以不同的配置构建。

可以通过发送给编译器的附加 -D 来区分配置 ,即 -DHARDWARE_FOO-DHARDWARE_BAR。当配置更改时,我通常需要通过这样做来清理所有对象文件:

make clean all

否则 make 不会重建项目,因为 none 的依赖项已更改。

避免手动清理项目的简单解决方案是使用名为 configuration 的文本文件,其中包含当前配置的名称。在Makefile中我们会发现:

%o:%c $(CONFIGURATION) 
   $(cc) -c $< -o $@ -D$(shell cat $(CONFIGURATION))

不幸的是,每次配置更改时,这仍然需要重建整个项目。

我觉得如果我能够告诉 make 只重建依赖于声明的文件,这个解决方案可以优化 $(CONFIGURATION) HARDWARE_xxx .

这可以节省很多时间,尤其是当不同硬件的数量很大时。在我的具体案例中,我谈论的是可以在不同硬件平台上 运行 的嵌入式固件。硬件平台由发送给编译器的定义标识。所以在源代码中我们会发现很多 #ifdef ... #elif ... #endif 指令

关于这个问题,我最初的想法是使用一个脚本 getdependencies,它会递归地检查所有 C 文件(及其包含文件),以确定哪些文件依赖于配置。

所以在 Makefile 我会发现:

-import configurations.d
configurations.d: configuration
    getdependencies --configuration=$< $(SRCS)

我对此进行了一些研究,看看是否已经存在类似的解决方案,因为我不想重新发明轮子。不幸的是我没有找到这样的东西。

有什么想法吗?

我认为这种情况下的标准方法是在 makefile 中为每个配置定义一个目标并配置工具(编译器、链接器、库管理器、汇编器、资源 builder/compilers 等)创建他们为每个配置生成的文件放在一个单独的目录中(使用配置名称作为目录名称)。

此更改为您的构建例程带来了副作用改进:您可以通过简单地 运行 make 在命令行中使用关联目标来构建配置(不再更改文件)。然而,主要的改进是编译器将只重新编译被修改的文件(因为配置不再共享目标文件和可执行文件)。