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

时间:2014-11-01 01:02:34

标签: c++ c sed makefile

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

#include <stdio.h>

#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

2 个答案:

答案 0 :(得分:2)

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

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

year.c

#include <stdio.h>

#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做一些更复杂的事情,以便在必要时克服这个问题。

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

答案 1 :(得分:2)

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

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