扩充现有的Makefile

时间:2017-04-27 01:02:23

标签: c makefile autotools configure autoconf

我正在开发一个依赖于C库的现有程序,实际上是一个相当古老的程序,只有一个Makefile和一个README文件,它有一些修改指令makefile在不同的系统上成功编译。我的任务是清理程序的构建过程,因此它可以移植而不会破坏makefile等,所以这意味着确保C库是可移植的。

例如,MacOS的最新版本需要做的一件事就是正确定义SIZEOF_VOID_P,因为如果未定义则默认为4,这自然会导致64位系统出现可怕的段错误。我刚刚在Makefile中将其定义为8,但显然现在我已经为32位系统打破了它。

我的想法最初只是写一个C文件的输出有一些#ifdef s吐出适当的定义,如果他们错过了输出到现有makefile的前置,但它似乎有点hacky。标准配置脚本似乎无论如何都会自己完成所有这些,所以我想为什么不使用它们。我读到可以使用autoconf生成配置脚本,但我不想删除现有的makefile(我担心这可能会导致比它解决的更多问题)。我只是想为它们添加一些适当的定义。

这有什么好处吗?

2 个答案:

答案 0 :(得分:1)

如果不能选择autoconfcmake或类似程序,您可以执行与您自己的想法类似的操作。

CC=gcc

.PHONY: all

all: main

pre-build:
        $(CC) constants.c -o constants
        $(eval SIZEOF_VOID_P = $(shell ./constants "SIZEOF_VOID_P"))
        $(eval FOOBAR = $(shell ./constants "FOOBAR"))

main: pre-build
        @echo $(SIZEOF_VOID_P) $(FOOBAR)

程序constants属于

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ALL CHECKS AND BALANCES OMITTED!

int main(int argc, char **argv){
  if(argc != 2){
    fprintf(stderr,"Usage: %s constant_to_test\n",argv[0]);
    exit(EXIT_FAILURE);
  }
  // good for a couple of constants but should be changed
  // to a proper parser if you have more than a dozen or so
  if(strncmp(argv[1], "SIZEOF_VOID_P", 13 ) == 0){
    printf("%zu\n",sizeof(void *));
  }
  else if (strncmp(argv[1], "FOOBAR", 6) == 0){
    printf("%d\n",42);
  }
  // ...
  else {
    fprintf(stderr,"Constant %s unknown\n",argv[1]);
    exit(EXIT_FAILURE);
  }
  exit(EXIT_SUCCESS);
}

到目前为止,它不是最优雅的解决方案,但如果您需要的只是一些常量,它的效果很好。另一方面:对于更复杂的事情,它会很快变得非常讨厌,例如:找到正确编译器的路径并使用正确的参数调用它,找到一些库的路径并检查它们是否是正确的,等等等等。

答案 1 :(得分:0)

  

我不想丢弃现有的makefile(我担心它可能会导致比它解决的更多问题)。我只是想为它们添加一些适当的定义。

     

这有什么好处吗?

如果您准备假设GNU make,那么您可以依赖其include指令将外部文件中的Makefile片段包含到现有的Makefile中。您可以修改现有的Makefile,在顶部或顶部附近添加一个或多个include指令,代替需要调整以适应构建环境的部分。然后编写一个程序来分析系统并将相应的Make变量定义输出到相应的文件中。 include指令不是POSIX make的标准功能,但它可能不是一个可行的选项。

或者,可以在命令行上指定make变量定义。例如,

make all SIZEOF_VOID_P=8

原则上,您可以通过以这种方式提供定义的包装脚本调用make来设置所需的所有make变量。这样的脚本可能会动态确定所需的值,或者您可以通过单独的配置程序生成脚本。无论哪种方式,您可能需要修改现有的Makefile以抑制(重新)定义所涉及的变量。