从 Makefile 转换为 cmake *之后,app 和 lib 中的同名类会导致问题
我正在尝试将程序及其插件从自定义 Makefile 转换为 CMake,并对代码进行最少的更改。
插件和应用程序共享一些代码; #ifdef ... #else ... #endif 块用于存在差异的地方,并且我确信代码是使用正确的定义进行编译的。共享代码包括一个名为 ToolImage 的类。当为应用程序编译代码时,ToolImage 构造函数使用与为插件编译时不同的资源路径。
#ifdef THE_APP
ToolImage::ToolImage(const wxString& name, bool full_path_given):wxImage(full_path_given?name:
(wxGetApp().GetResFolder() + _T("/bitmaps/") + name + _T(".png")), wxBITMAP_TYPE_PNG)
#else
ToolImage::ToolImage(const wxString& name, bool full_path_given):wxImage(full_path_given?name:
(theApp.GetResFolder() + _T("/bitmaps/") + name + _T(".png")), wxBITMAP_TYPE_PNG)
#endif
{
...
}
当程序及其插件使用自定义 Makefile 进行编译后,一切都会按预期工作。当两者都使用 CMake 进行编译时,使用我创建的一系列 CMakeLists.txt 文件,存在一个问题:插件无法加载其工具栏的位图。
我将问题跟踪到 ToolImage 类。 gdb 给出的行号告诉我该插件使用了错误的构造函数。 strace 告诉我同样的事情(插件正在应用程序的资源目录中查找其位图,而不是在插件的资源目录中)。为了确保我没有搞砸定义,我在 ToolImage.cpp 中放置了一个 #error,位于仅应为应用程序编译的 #ifdef 部分内 - 并且插件仍然编译没有错误。这告诉我该插件正在使用正确的代码进行编译。由于它使用了错误的路径,我认为它使用的是编译到程序中的类和构造函数而不是它自己的。
如何确保插件使用自己的 ToolImage 类而不是应用程序中的类?!我不拥有该项目,也不想仅仅为了支持使用不同的构建系统进行构建而进行大量更改。
对我来说,使用预编译器创建一个类的两个版本似乎是一个糟糕的选择。如果我必须更改代码,您有解决方法的建议吗?
I'm trying to convert a program and its plugin from custom Makefiles to CMake, with minimal changes to the code.
Both the plugin and the app share some code; #ifdef ... #else ... #endif blocks are used where there are differences, and I'm certain the code is compiled with the correct defines. The shared code includes a class called ToolImage. When the code is compiled for the app, the ToolImage constructor uses a different resource path than when it is compiled for the plugin.
#ifdef THE_APP
ToolImage::ToolImage(const wxString& name, bool full_path_given):wxImage(full_path_given?name:
(wxGetApp().GetResFolder() + _T("/bitmaps/") + name + _T(".png")), wxBITMAP_TYPE_PNG)
#else
ToolImage::ToolImage(const wxString& name, bool full_path_given):wxImage(full_path_given?name:
(theApp.GetResFolder() + _T("/bitmaps/") + name + _T(".png")), wxBITMAP_TYPE_PNG)
#endif
{
...
}
When the program and its plugin have been compiled with the custom Makefiles, everything works as expected. When both have been compiled with CMake, using a series of CMakeLists.txt files I created, there is an issue: the plugin isn't able to load the bitmaps for its toolbar.
I tracked the problem to the ToolImage class. The line number given by gdb tells me that the plugin is using the wrong constructor. strace tells me the same thing (the plugin is looking for its bitmaps in the app's resource dir rather than in the plugin's resource dir). To ensure that I didn't have the defines screwed up, I put a #error in ToolImage.cpp, inside the part of the #ifdef that should only be compiled for the app - and the plugin still compiled without error. This tells me that the plugin is compiling with the correct code. Since it is using the wrong path, I think it is using the class and constructor compiled into the program instead of its own.
How do I ensure that the plugin uses its own ToolImage class instead of the one in the app?! I don't own the project and don't want to make massive changes merely to support building with a different build system.
Using the precompiler to create two versions of a class seems like a poor choice to me. If I must make changes to the code, do you have suggestions for a workaround?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了进行实验,我会在构建应用程序时将 -fvisibility=hidden 添加到所有源或某些特定源。这应该从插件中隐藏应用程序的 ToolImage。
它不是通用方法,因为在许多情况下插件确实使用与主可执行文件不同的符号。
For the sake of experiment, I'd add -fvisibility=hidden when building theapp, to all or maybe to some specific sources. This should hide application's ToolImage from the plugin.
It is not a universal method, as in many cases plugins do use different symbols from the main executable.
我通过在 CMakeLists.txt 中添加链接器标志 -Wl,-Bsymbolic-functions 修复了此问题:
I fixed this by adding the linker flag -Wl,-Bsymbolic-functions in the CMakeLists.txt: