【问题标题】:Export C #defines as shell variables将 C #defines 导出为 shell 变量
【发布时间】:2010-02-12 11:04:17
【问题描述】:

在我的项目中,系统的各种目录、文件和其他组件的许多路径以#defines 的形式存储在filenames.h 中,所有需要它们的人都包含该文件。它适用于编译生成的所有各种二进制文件,但该项目还包括一些使用相同路径的 shell 脚本。目前这意味着当路径发生变化时,我所要做的就是编辑 filenames.h 并重新编译以获取可执行文件集以理解新路径,但我必须手动编辑每个 shell 脚本。

所以问题是,如何将#defines 转换为shell 变量,例如生成一些filenames.sh 脚本,该脚本将从其他脚本中调用以对其进行初始化。比如:

#define TMP_PATH      "/ait/tmp/"
#define SYNCTMZFILE   TMP_PATH "sync_tmz"

会创造

TMP_PATH="/ait/tmp/"
SYNCTMZFILE="/ait/tmp/sync_tmz" 

当然可以编写一个创建它的 C 程序(甚至将其打印到标准输出,然后在 shell 中以反引号执行),但我更喜欢更简单的,更健壮的方法,例如,编写一个通过 cpp 运行的类似半 C 半壳的东西会创建正确的输出,或类似的东西。

【问题讨论】:

    标签: c shell environment-variables c-preprocessor header-files


    【解决方案1】:

    把它放在你的 Makefile 中:

    filenames.sh: filenames.h
            awk '/^#define/{print;printf "_%s=%s\n",$2,$2}' $< \
            | cpp -P \
            | sed 's/^_//;s/" "//;' > $@
    

    【讨论】:

    • 不幸的是,它不能很好地处理第二个#define 中的复合语句。
    【解决方案2】:

    反过来——将主脚本保留为 shell 脚本并从中生成标头——会更容易。如果你的 header 非常风格化,你可以编写一个 shell 脚本(或使用 awk/sed/perl/...)来解析它并生成 shell 片段。

    【讨论】:

      【解决方案3】:

      如果您使用make 构建程序并且shell 脚本由make 作为构建过程的一部分执行,您可以将其转过来:

      • 为您的Makefile 中的变量提供单一来源。
      • 将它们导出到 shell 脚本环境。
      • 将它们作为命令行选项传递给 C 编译器。 (这假设您的编译器支持-D parameter 或类似的东西。)

      示例(未经测试):

      export TMP_PATH := /ait/tmp/
      export SYNCTMZFILE := $(TMP_PATH)sync_tmz
      CFLAGS += -DTMP_PATH="$(TMP_PATH)" -DSYNCTMZFILE="$(SYNCTMZFILE)"
      

      如果您不使用make-D 选项仍然可能对您有用:您可以在 shell 脚本中而不是在头文件中单一来源变量。

      【讨论】:

      • 当路径改变时,像这样的 CFLAGS 可能不会为增量编译重建对象。取决于生成文件。从 Make 或它调用的脚本生成 C 标头可能更好。
      猜你喜欢
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 2021-08-07
      • 2011-12-28
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多