[CMake] WINDOWS_EXPORT_ALL_SYMBOLS invalid .def file

Balázs Oroszi orobalage at gmail.com
Tue Jun 13 13:32:19 EDT 2017


Hi,

I'm porting a rather large project/library from Linux to Windows and was
looking for an automatic symbol export solution, and found the
WINDOWS_EXPORT_ALL_SYMBOLS to be excellent. It works almost nicely, however
there is a problem with the .def file it creates.
Upon linking I get errors like this:

exports.def : warning LNK4022: cannot find unique match for symbol
'_CT??_R0?AU?$error_info_injector'
exports.def : warning LNK4002:
_CT??_R0?AU?$error_info_injector at Ubad_day_of_month@gregorian at boost
@@@exception_detail at boost@@@864 defined in ...
exports.def : warning LNK4002: _CT??_R0?AU?$error_info_injector at Ubad_month
@gregorian at boost@@@exception_detail at boost@@@864 defined in ...
...
exports.def : error LNK2001: unresolved external symbol
_CT??_R0?AU?$error_info_injector
...

So first several warnings then finally errors. MSDN also sais this:
https://msdn.microsoft.com/en-us/library/3802xyyy.aspx

Apparently, the .def file has lines like this which cause the problem:
_CT??_R0?AU?$error_info_injector DATA
...

If I manually delete the lines referenced in the above errors from the
generated .def file, the DLL builds fine.

The project uses a lot of third party libraries, boost is one of them. The
symbols that cause the problem are probably not even need to be exported.

So my question is, how can I solve this? My first idea was to create a sort
of "blacklist" and write a script that "heals" the .def file by removing
the problematic lines. However it is not possible to do, as
the WINDOWS_EXPORT_ALL_SYMBOLS step is added internally by CMake as a final
PRE_LINK step, and I found no way add a command between the .def file
generation and the actual linking.

I thought about adding a custom command which would emulate the behaviour
of WINDOWS_EXPORT_ALL_SYMBOLS, however I cannot easily get the object file
list in a convenient file as WINDOWS_EXPORT_ALL_SYMBOLS does.

So I'm stuck at this point, any help would me much appreciated.

Additional BUG:
I probably found a bug as well in the process. If I enable
WINDOWS_EXPORT_ALL_SYMBOLS but I also add a custom PRE_LINK step with
add_custom_command() like this:

add_custom_command(TARGET zp_core PRE_LINK COMMAND echo Hello)

then I get the following output:

...
Hello
Couldn't open file
'lib\core\CMakeFiles\zp_core.dir\background_thread.cpp.obj' with
CreateFile()

It seems when I add the custom command, then CMake first changes the
directory like so (using blabla as example):

cmd.exe /C "cmd.exe /C "cd /D C:\blablabla && echo Hello && "C:\Program
Files\CMake\bin\cmake.exe" -E __create_def ...

while if there is no custom command present, it looks like this:

cmd.exe /C "cmd.exe /C ""C:\Program Files\CMake\bin\cmake.exe" -E
__create_def

I believe in the custom command case the "__create_def" step is executed in
the wrong working directory and CMake fails to open the object file listed
in the exports.def.objs list.

Thanks in advance,
Balázs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20170613/30cb95fe/attachment.html>


More information about the CMake mailing list