代码之家  ›  专栏  ›  技术社区  ›  Nitro

获取已定义变量的值

  •  0
  • Nitro  · 技术社区  · 6 年前

    我正试图编写一个makefile来自动化编译、将代码推送到服务器和运行代码的工作。

    问题是我没有定义服务器的列表,而且会有其他人使用这个makefile。

    我想做的是以下几点。

    假设有一个代码C代码

    #include<stdio.h>
    #define SERVER_NAME "Some Server"
    
    int main(int argc, char** argv)
    {
       //Some random code
    }
    

    在makefile中是否有任何工具可以使用,我将把c文件及其所有依赖项传递给它,并且该工具将告诉我(由于缺少更好的字)变量“server_name”定义为什么?

    我需要这种东西

    <Some tool> <c file initially created> <all include files> <any c specific switch>
    

    输出是这样的

    SERVER_NAME="Some Server"
    

    我知道我可以在文件上做一个grep并拉变量,但是我也要注意下面这样的条件。

    #include<stdio.h>
    #define SERVER1 //This might change to server2
    #ifdef SERVER1
    #define SERVER_NAME "Some Server 1"
    #endif
    #ifdef SERVER2
    #define SERVER_NAME "Some Server 2"
    #endif
    
    int main(int argc, char** argv)
    {
       //Some random code
    }
    

    我知道C预处理器足够强大,可以完成这项工作,我只是不知道传递给它的参数或开关是什么。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Beta    6 年前

    GCC预处理器选项 -imacros 允许扫描源文件中的宏并忽略其余宏。

    假设源文件名为 foo.cc 以下内容:

    #define SERVER1 //This might change to server2
    #ifdef SERVER1
    #define SERVER_NAME "Some Server 1"
    #endif
    #ifdef SERVER2
    #define SERVER_NAME "Some Server 2"
    #endif
    
    int main(int argc, char** argv)
    {
       //Some random code
    }
    

    编写另一个名为 serverReporter.cc 以下内容:

    #include <iostream>
    using std::cout;
    using std::endl;
    
    int main()
    {
      cout << "SERVER_NAME=" << SERVER_NAME << endl;
      return 0;
    }
    

    现在生成(有或无make):

    g++ -imacros foo.cc serverReporter.cc -o serverReporter
    

    然后运行它。

    (可能有一种方法可以在不运行代码的情况下通过如下选项获取宏值 -dD 但是我还没把它用起来。)

        2
  •  0
  •   Florian Weimer    6 年前

    假设您的头文件不声明任何其他常量(对于C++代码来说可能是一个扩展),您可以编译这样的文件:

    // Comes from a header file
    #define SERVER_NAME "server name"
    
    const char compile_time_server_name[] = SERVER_NAME;
    

    生成的对象文件的常量数据部分将包含字符串。例如,如果你的目标是精灵,你可以使用 objcopy 从binutils提取此数据:

    objcopy -O binary -j .rodata server_name.o server_name.contents
    

    命令 xxd server_name.contents 显示如下:

    00000000: 7365 7276 6572 206e 616d 6500            server name.
    

    注意后面的nul;您可能需要通过进一步的脚本来删除它。最好检查boject文件是否只包含 .rodata 部分,可能使用 nm .