Open timdewhirst opened 3 months ago
Exporting of symbols is done through dumpbin /exports or dumpbin /linkermember.
I put __declspec(dllexport) on c++ classes with source files and it seems that Meson is able to produce .lib files on its own. However, I get a link error like such:
FAILED: tests/grid_test.exe "link" /MACHINE:x64 /OUT:tests/grid_test.exe tests/grid_test.exe.p/grid_test.cpp.obj "/nologo" "/release" "/nologo" "/OPT:REF" "openpiv\openpiv.lib" "subprojects\tiff-4.4.0\libtiff\tiff4.lib" "subprojects\Catch2-3.4.0\src/catch2\libCatch2.a" "subprojects\Catch2-3.4.0\src/catch2\libCatch2Main.a" "/SUBSYSTEM:CONSOLE" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "comdlg32.lib" "advapi32.lib" Creating library tests\grid_test.lib and object tests\grid_test.exp grid_test.cpp.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits
> & cdecl openpiv::core::operator<<(class std::basic_ostream<char,struct std::char_traits > &,class openpiv::core::rect const &)" (??6core@openpiv@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AEAV23@AEBVrect@01@@Z) referenced in function "public: struct Catch::MessageBuilder && cdecl Catch::MessageBuilder::operator<<<class std::vector<class openpiv::core::rect,class std::allocator> >(class std::vector<class openpiv::core::rect,class std::allocator > const &)&& " (??$?6V?$vector@Vrect@core@openpiv@@V?$allocator@Vrect@core@openpiv@@@std@@@std@@@MessageBuilder@Catch@@QEHAA$$QEAU01@AEBV?$vector@Vrect@core@openpiv@@V?$allocator@Vrect@core@openpiv@@@std@@@std@@@Z) tests\grid_test.exe : fatal error LNK1120: 1 unresolved externals
From memory there are two parts to this problem:
Of course the alternative is just to build a fully static library... there's not much downside to this as the core functionality is pretty small, and in fact it should give a small performance improvement.
Static compilation has the following error
../tests/image_algos_test.cpp(30): FAILED: REQUIRE( save_to_file( "fft-input.pgm", im ) ) due to unexpected exception with message: failed to find image writer
This error also occurs for the tif image loader.
../tests/image_algos_test.cpp(132): FAILED: due to unexpected exception with message: failed to find loader for corr_a.tiff
Additionally, the link error on the dll when compiling dynamically seems to be caused by https://github.com/OpenPIV/openpiv-c--qt/blob/8bdf76ee10cf8298dd7f366a79aa079af94e0040/openpiv/core/rect.h#L77 The issue could be caused by the overload not being exported since it is not part of a class member.
Exporting operator << overloads fixes the problem! Compiles sucessfully with MS Visual Studio 2019 and 2022.
I encountered an unexpected side effect of using Meson's dl export functionality. Although all executables compile and link properly, the executables are exporting symbols as such:
dumpbin /exports image_test.exe
Microsoft (R) COFF/PE Dumper Version 14.34.31937.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file image_test.exe
File Type: EXECUTABLE IMAGE
Section contains the following exports for image_test.exe
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
39 number of functions
39 number of names
ordinal hint RVA name
1 0 000038D0 ??0image_loader@core@openpiv@@QEAA@AEBV012@@Z
2 1 000038D0 ??0image_loader@core@openpiv@@QEAA@XZ
3 2 00003980 ??0rect@core@openpiv@@QEAA@$$QEAV012@@Z
4 3 00003980 ??0rect@core@openpiv@@QEAA@AEBV012@@Z
5 4 000039A0 ??0rect@core@openpiv@@QEAA@XZ
6 5 000039F0 ??0size@core@openpiv@@QEAA@$$QEAV012@@Z
7 6 000039F0 ??0size@core@openpiv@@QEAA@AEBV012@@Z
8 7 00003A00 ??0size@core@openpiv@@QEAA@II@Z
9 8 00003A10 ??0size@core@openpiv@@QEAA@XZ
10 9 00004220 ??1image_loader@core@openpiv@@UEAA@XZ
11 A 00004370 ??4image_loader@core@openpiv@@QEAAAEAV012@AEBV012@@Z
12 B 00004370 ??4image_loader_registry@core@openpiv@@QEAAAEAV012@$$QEAV012@@Z
13 C 00004370 ??4image_loader_registry@core@openpiv@@QEAAAEAV012@AEBV012@@Z
14 D 00004380 ??4rect@core@openpiv@@QEAAAEAV012@$$QEAV012@@Z
15 E 00004380 ??4rect@core@openpiv@@QEAAAEAV012@AEBV012@@Z
16 F 000043A0 ??4size@core@openpiv@@QEAAAEAV012@$$QEAV012@@Z
17 10 000043A0 ??4size@core@openpiv@@QEAAAEAV012@AEBV012@@Z
18 11 000043B0 ??8size@core@openpiv@@QEBA_NAEBV012@@Z
19 12 000043C0 ??9size@core@openpiv@@QEBA_NAEBV012@@Z
20 13 0005EB00 ??_7image_loader@core@openpiv@@6B@
21 14 00009B60 ?area@rect@core@openpiv@@QEBAIXZ
22 15 00009B70 ?area@size@core@openpiv@@QEBAIXZ
23 16 00009CF0 ?bottom@rect@core@openpiv@@QEBAHXZ
24 17 00009D00 ?components@size@core@openpiv@@QEBA?AV?$array@I$01@std@@XZ
25 18 00009E40 ?height@rect@core@openpiv@@QEBAIXZ
26 19 00009CF0 ?height@size@core@openpiv@@QEBAIXZ
27 1A 00009E50 ?height_@size@core@openpiv@@AEAAAEAIXZ
28 1B 00009E50 ?height_@size@core@openpiv@@AEBAAEBIXZ
29 1C 00009EB0 ?left@rect@core@openpiv@@QEBAHXZ
30 1D 00009FA0 ?load@image_loader@core@openpiv@@UEAA_NAEAV?$basic_istream@DU?$char_traits@D@std@@@std@@AEAV?$image@U?$g@G@core@openpiv@@@23@@Z
31 1E 00009FF0 ?load@image_loader@core@openpiv@@UEAA_NAEAV?$basic_istream@DU?$char_traits@D@std@@@std@@AEAV?$image@U?$g@N@core@openpiv@@@23@@Z
32 1F 0000A040 ?load@image_loader@core@openpiv@@UEAA_NAEAV?$basic_istream@DU?$char_traits@D@std@@@std@@AEAV?$image@U?$rgba@G@core@openpiv@@@23@@Z
33 20 0000A670 ?right@rect@core@openpiv@@QEBAHXZ
34 21 0000AB60 ?size@rect@core@openpiv@@QEBAAEBV023@XZ
35 22 0000BDB0 ?top@rect@core@openpiv@@QEBAHXZ
36 23 0000C180 ?width@rect@core@openpiv@@QEBAIXZ
37 24 00009EB0 ?width@size@core@openpiv@@QEBAIXZ
38 25 00004370 ?width_@size@core@openpiv@@AEAAAEAIXZ
39 26 00004370 ?width_@size@core@openpiv@@AEBAAEBIXZ
Summary
5000 .data
5000 .pdata
1B000 .rdata
1000 .reloc
5D000 .text
This could be eliminated using .def files with all symbols to create the dynamic library instead of dll exports, however the import lib would be much more messier due to lots of symbols being exported through libopenpivcore (very similar to CMake's WINDOWS_EXPORT_ALL_SYMBOLS).
Here is the executable symbol table using CMake's WINDOWS_EXPORT_ALL_SYMBOLS
dumpbin /exports image_test.exe
Microsoft (R) COFF/PE Dumper Version 14.34.31937.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file image_test.exe
File Type: EXECUTABLE IMAGE
Summary
4000 .data
5000 .pdata
19000 .rdata
1000 .reloc
1000 .rsrc
5A000 .text
Issue is now fixed with preprocessor directives.
Here is an interesting performance test. I wonder why GCC is so much faster (especially because I did not set any simd or mtune flags)?
Performance of MSVC (Visual Studio 2022) compared to GCC 10 in release build (average of 10 runs) | Compiler | Time / IW in microseconds) |
---|---|---|
msvc | 10.22 | |
gcc | 6.79 |
It seems that I broke the Linux build again (-_-) See here for the segmentation violation fault. Other than that, Windows using Visual Studio (I'll have to update the CI to use Visual Studio instead of GCC) and Mac OS build tests pass.
Linking pull request for this feature (#46)
One method for exporting symbols on the Meson MSVC build is to compile a static library, export all symbols from that static library, then compile the dll using the .def file and the object files from the static library (or recompile the object files, I forgot which one). This method apparently works enough that some use it at their workplace and has the added benefit of not requiring __declspec(dllexport).