Question

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?

Was it helpful?

Solution 2

I fixed this by adding the linker flag -Wl,-Bsymbolic-functions in the CMakeLists.txt:

set_target_properties( heekscnc PROPERTIES LINK_FLAGS -Wl,-Bsymbolic-functions )

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top