Individual export files

I was wondering about the export header files created for targets built by the SlicerMacroBuild* suite of cmake scripts. Is there a reason for all of these to be separate and configured?

Slicer-build$ find ./ -name *Export.h | wc -l
119

Some are unique or custom, but the significant majority are templated from CMake/qSlicerExport.h.in, or a slightly-different template from CTK for plugins.

I took a quick look through them:

$ cat `find ./ -name *Export.h | grep -v Plugin` | less

They all look identical – except for the actual name, of course – so they could potentially be replaced with a single slicer_export.h which defines Slicer_EXPORT.

I think the current implementation is necessary if we want to allow building a module that depends on another module.

Example: Module A depends on module B. When you build module A, symbols of module A must be exported (using __declspec(dllexport)), while symbols of module B must be imported (using __declspec(dllimport)). If you used a single Slicer_EXPORT then both module symbols would be imported or both would be exported.

Do you have a specific idea how the current implementation could be simplified?

1 Like

I forgot that CMake is automatically adding -D{LIBNAME}_EXPORTS at compile time to do the switch. Thanks, it makes more sense.

In light of above, I agree this is nice and simple. We could probably make a single-header version with -DLIBNAME=NAME and some preprocessor substitution, but that just adds a different kind of magic, and this is overall a small point. So not worth the effort/churn.

1 Like

We’ve discussed this a bit more with @ihnorton.

Here is how CMake adds the compiler definition when it generates the target:

The same mechanism is implemented in Visual Studio IDE, so very similar macros are used when projects are created without CMake: “By default, the New Project template for a DLL adds PROJECTNAME_EXPORTS to the defined preprocessor symbols for the DLL project.” (source).

1 Like