如何在编译期间编辑可执行文件而不更改其源代码?

我必须编写一个编译文件year.c的Makefile,然后它会显示当前年份(2014),而不是前一年(2013)。我尝试过使用sed函数,但只有在我使用make时才有效跑 。

#include  #ifndef YEAR #define YEAR "2013" #endif int main(){ printf("Hello world from " YEAR "\n"); return 0; } 

和Makefile:

 year: year.c gcc year.c -o year run: ./year | sed -e 's/3/4/g' clean: rm year Makefile 

只需在命令行中定义YEAR#ifndef将确保它不会被重新定义:

 gcc -DYEAR=\"2014\" -o year year.c 

在这种特殊情况下,直接在您的计划中计算年份是一个更好的解决方案,如评论中所述。

但是,一般情况下,您需要使run依赖于year 。 这是一个使用中间文件的解决方案,它不会覆盖year.c ,但如果您愿意,可以修改它以覆盖:

year.c

 #include  #ifndef YEAR #define YEAR "2013" #endif int main(void) { printf("Hello world from " YEAR "\n"); return 0; } 

Makefile

 year: run gcc year_manip.c -o year run: cat year.c | sed -e 's/3/4/g' > year_manip.c 

示例会话:

 paul@horus:~/src/sandbox/year$ ls Makefile year.c paul@horus:~/src/sandbox/year$ make cat year.c | sed -e 's/3/4/g' > year_manip.c gcc year_manip.c -o year paul@horus:~/src/sandbox/year$ ./year Hello world from 2014 paul@horus:~/src/sandbox/year$ 

请注意,此解决方案意味着您的程序将始终编译,即您的run目标永远不会是最新的。 如果你使它依赖于year.cyear_manip.c ,那么当2015年出现时,它仍然不会重建,这可能不是你想要的。 如果有必要,你可以做一些更复杂的make ,以克服这个问题。

对于这个特殊的问题,当问题纯粹是一个带有值的标识符的定义之前, 链接问题的答案显然提供了一个更简单的方法,可以在这里工作。 对于更通用的代码生成,以这种方式使用makefile非常有用。