It appears to be the case that all current tests in the netcdf-c source tree are integration tests. That is they only access the library using calls to the externally visible API.
The DAP4 code testing is different in that it includes (for the first time) unit tests. These tests reference code that is considered internal to the library. For the library generated under autoconf, this is not a problem because those symbols are visible in the library: nothing is hidden.
However, when using cmake and Visual Studio, the occurrence of _declspec(dllimport) and _declspec(dllexport) tags causes all symbols to be hidden except those explicitly exported via _declspec(dllexport). This declaration is hidden by the EXTERNL macro (see e.g. include/netcdf.h and netcdf_mem.h).
This means that unit tests will not work when loaded with the netcdf library using the targetlinklibrary() function in cmake.
In any case, and in order to get around this, I1. hypothesized the following options.
- Build two versions of the library: one for integration tests and installation and one for unit tests. One possible way to do this is to use a Visual Studio .dep file to export the otherwise hidden symbols. Frankly, I have no idea how do to this under cmake.
- Use the ADD_LIBRARY(X OBJECT ...) + $<TARGET_OBJECTS...> mechanism to load the individual object files containing the symbols needed for unit testing.
Neither solution is appealing.
I attempted to use the #2 approach, but it failed. It appears the the ADD_LIBRARY(... OBJECT ...) command does not operate as I expected. Perhaps someone else can figure out how to make this work.
So, for now, I have expunged the unit tests when building using cmake.
The top-level CMakeLists.txt defines what I call a "shift point" where _declspec(dllimport) is used instead of _declspec(dllexport). This is defined by the command REMOVEDEFINITIONS(-DDLLEXPORT).
We could suppress all internal symbols from the netcdf library generated by autoconf. We would do so by using a program like strip to only expose the exact netcdf library API and hide all other symbols. The proper time to do this would be as part of an install-hook that hid the symbols at the point when the library was being installed.
Note that any .h file that includes _declspec (vid EXTERNL) must be referenced by code compiled before the shift point (see above) in the CMakeLists.txt file. But watch out that no API function in the .h file is duplicated int some other .h file in order to prevent complaints by cmake about linkage errors.
EXTERNL should not be used except in include/*.h files that are intended to define an external API.