在 C++ 编译时以字符串形式检索输出目标名称

发布于 2024-10-20 02:52:17 字数 563 浏览 3 评论 0原文

我有一个可以在多个平台上编译的项目... Windows、Unix、Linux、SCO,说出你的风格。

我想将输出目标的名称填充到项目源代码中的变量中(输出程序的名称、DLL、SO 库或其他名称),这样我就可以在消息中使用它作为引用组件名称的通用方法Windows 上的 EXE、DLL、Unix 上的 SO 库等。

我想到的是像 FUNCTION_ 这样的预处理器键,但可以在 Windows 上提取 EXE/DLL 的名称Visual C++,然后是 GCC 中的 SO 输出库。当然,这些可能是两种不同的机制,但我想将这两种机制合并为一个选项,我可以在我的多平台代码中通用使用它。

因此,我可以调用一个宏的东西或其他东西,它至少在编译期间获取 Windows 输出文件名(Visual C++),这样我就可以将其推入代码中的 const 字符串中,也许是一种在GCC 因此可以将两个平台包装成一个抽象。最好不在运行时获取,但在编译期间捕获并保留。

如果输出是库,则它是 lib 文件名。如果是组件,则输出组件文件名。

我希望 Boost 或 Poco 必须已经有类似的东西,可能有一些不受支持的端点,这很好。

I have a project which compiles in multiple platforms... Windows, Unix, Linux, SCO, name your flavor.

I would like to stuff the output target's name into a variable in the project source code (the name of the output program, DLL, SO library or whatever) so I can use it in messages as a generic way to reference the component name be it an EXE on Windows, a DLL, an SO library on Unix, etc.

What I'm thinking of is a preprocessor key like FUNCTION_ but something to pull the name of the EXE/DLL on Windows in Visual C++, and then secondarily the SO output library in GCC. Those are probably going to be two different mechanisms of course, but I figure to coalesce the two into one option that I can use generically in my multiplatform code.

So a macro'ish thing or something I can call which at least picks up the Windows output file name during compilation (Visual C++) so I can push it into a const string in the code, and maybe a way to do the same thing in GCC so the two platforms can be wrapped into an single abstraction. Preferably not picked up at runtime but caught and persisted during compilation.

If the output is a library, then its the lib file name. If it's a component, then the output component file name.

I expect Boost or Poco must have something like this already possibly with some unsupported endpoints which is fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

没有你我更好 2024-10-27 02:52:17

如果所有内容都集中在一个项目下,则可以使用预处理器宏。要在 Visual Studio 中执行此操作,请打开项目属性并转到“配置属性”>“配置属性”。 C/C++>预处理器,并将类似 PROGRAM_NAME="\"$(ProjectName)\"" 添加到 Preprocessor Defines 字段(对应于 /Dfoo=bar 编译器选项)。

对于 GCC,请使用类似的 -Dfoo=bar 命令行选项。例如,您的 Makefile 可能如下所示:

PROGRAM_NAME = myapplication
CFLAGS += '-DEXECUTABLE_NAME="$(PROGRAM_NAME)"'

# Rule to make the executable from the object files
$(PROGRAM_NAME): $(OBJS)
    $(LD) $(OBJS) -o $@ $(LDFLAGS)

# Rule to make object files from C source files
%.o: %.c
    $(CC) $(CFLAGS) -c 
lt; -o $@

这允许您的源文件使用宏 PROGRAM_NAME,在本例中它将扩展为常量字符串 "myapplication"

但是,如果您有链接到多个程序的目标文件(例如,您有大量共享库代码,可以由主程序驱动程序或各种测试套件运行),则目标文件无法知道哪个可执行文件他们被提前链接到,所以他们必须在运行时确定。

在这种情况下,请使用常量全局变量来存储程序名称,并使用上述技术在每个可执行文件的主源文件中定义和初始化它。

If everything is together under one project, you can use a preprocessor macro. To do this in Visual Studio, open up your project properties and go to Configuration Properties > C/C++ > Preprocessor, and add something like PROGRAM_NAME="\"$(ProjectName)\"" to the Preprocessor Defines field (which corresponds to the /Dfoo=bar compiler option).

For GCC, use the similar -Dfoo=bar command line option. For example, your Makefile might look something like this:

PROGRAM_NAME = myapplication
CFLAGS += '-DEXECUTABLE_NAME="$(PROGRAM_NAME)"'

# Rule to make the executable from the object files
$(PROGRAM_NAME): $(OBJS)
    $(LD) $(OBJS) -o $@ $(LDFLAGS)

# Rule to make object files from C source files
%.o: %.c
    $(CC) $(CFLAGS) -c 
lt; -o $@

This allows your source files to use the macro PROGRAM_NAME, which will expand to the constant string "myapplication" in this case.

However, if you have object files that are being linked into multiple programs (e.g. you have lots of shared library code which can be run either by the main program driver or by various test suites), then the object files can't know which executable they're being linked into ahead of time, so they have to determine that at runtime.

In that case, use a constant global variable to store the program name, and define and initialize that in each executable's main source file using the technique above.

§对你不离不弃 2024-10-27 02:52:17

编译器无法知道这一点。它是分配名称的链接器。我想说你最好的选择是定义或运行时确定模块名称(这不适用于静态库)

The compiler cannot know this. It's the linker that assigns a name. I'd say your best bet is a define, or runtime determining the module name (which won't work for static libs)

长不大的小祸害 2024-10-27 02:52:17

另一个解决方案,有点 hacky,是将代码中的 const 字符串设置为唯一的、易于定位且足够大的值,然后在链接完成后找到 & 。用您正在操作的文件的实际名称覆盖唯一值...

Another solution, a bit hacky, would be to set your const string in the code to a unique, easy to locate and big enough value and after the linking is done locate & overwrite the unique value with the actual name of file you're operating on...

寄风 2024-10-27 02:52:17

我的解决方案基于@Adam Rosenfield 的答案。

在我的 CMakeLists.txt 中创建了一个变量:

set(DLL_NAME myModuleDllName)

然后将宏添加到项目中,如下所示:

add_compile_definitions(DLL_NAME="${DLL_NAME}")

现在我可以在生成的 Visual Studio 项目中的任何位置使用该宏。

Based my solution on @Adam Rosenfield's answer.

In my CMakeLists.txt created a variable:

set(DLL_NAME myModuleDllName)

Then added the macro to the project like this:

add_compile_definitions(DLL_NAME="${DLL_NAME}")

Now I can use this macro everywhere in the generated Visual Studio project.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文