我正在尝试编写一个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预处理器的功能足以完成这项工作,我只能弄清楚要传递给它的参数或开关。
答案 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
。