获取已定义变量的值

时间:2018-06-17 09:40:10

标签: makefile preprocessor

我正在尝试编写一个makefile来自动完成编译工作,将代码推送到服务器,并将代码全部运行在一起。

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

我要做的是以下内容。

我们假设有一个代码c代码

#include<stdio.h>
#define SERVER_NAME "Some Server"

int main(int argc, char** argv)
{
   //Some random code
}

我是否可以在makefile中使用任何工具,我将传递C文件及其所有依赖项,该工具将告诉我(缺少更好的单词)变量&#34; SERVER_NAME&#34;被定义为?

我需要这种东西

<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 个答案:

答案 0 :(得分:1)

gcc预处理程序选项How to check if there is only one specific field who is updated with Firestore rules?允许您扫描源文件中的宏并忽略其余部分。

假设您的源文件名为allow update: if !("isAuthenticated" in request.writeFields);

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

现在构建(有或没有Make):

#include <iostream>
using std::cout;
using std::endl;

int main()
{
  cout << "SERVER_NAME=" << SERVER_NAME << endl;
  return 0;
}

并运行它。

(可能有一种方法可以在不运行代码的情况下通过像g++ -imacros foo.cc serverReporter.cc -o serverReporter 之类的选项获取宏值,但我还没有让它工作。)

答案 1 :(得分:0)

假设你的头文件没有声明任何其他常量(这可能对C ++代码有点延伸),你可以编译这样的文件:

// Comes from a header file
#define SERVER_NAME "server name"

const char compile_time_server_name[] = SERVER_NAME;

生成的目标文件将在其常量数据部分中包含该字符串。例如,如果您的目标是ELF,则可以使用binutils中的objcopy来提取此数据:

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