brechtsanders / xlsxio

XLSX I/O - C library for reading and writing .xlsx files
MIT License
397 stars 113 forks source link

fatal error - unresolved externals #102

Closed jakoch closed 2 years ago

jakoch commented 2 years ago

Hey!

I'm running into "fatal error LNK1120: 10 unresolved externals" when compiling and linking with MSVC 2019 using the vcpkg_target_triplet: x64-windows-static.

Error Message:

main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_open referenced in function "public: __cdecl XLSXReader::XLSXReader(char const *)" (??0XLSXReader@@QEAA@PEBD@Z) [D:\a\application\build\app.vcxproj]
main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_close referenced in function "public: __cdecl XLSXReader::~XLSXReader(void)" (??1XLSXReader@@QEAA@XZ) [D:\a\application\build\app.vcxproj]
main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_sheet_open referenced in function "public: class XLSXSheet * __cdecl XLSXReader::OpenSheet(char const *,unsigned int)" (?OpenSheet@XLSXReader@@QEAAPEAVXLSXSheet@@PEBDI@Z) [D:\a\application\build\app.vcxproj]
main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_sheet_close referenced in function "public: __cdecl XLSXSheet::~XLSXSheet(void)" (??1XLSXSheet@@QEAA@XZ) [D:\a\application\build\app.vcxproj]
main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_sheet_next_row referenced in function "public: bool __cdecl XLSXSheet::GetNextRow(void)" (?GetNextRow@XLSXSheet@@QEAA_NXZ) [D:\a\application\build\app.vcxproj]
main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_sheet_next_cell referenced in function "public: char * __cdecl XLSXSheet::GetNextCell(void)" (?GetNextCell@XLSXSheet@@QEAAPEADXZ) [D:\a\application\build\app.vcxproj]
main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_sheet_next_cell_string referenced in function "public: bool __cdecl XLSXSheet::GetNextCellString(char * &)" (?GetNextCellString@XLSXSheet@@QEAA_NAEAPEAD@Z) [D:\a\application\build\app.vcxproj]
main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_sheet_next_cell_int referenced in function "public: bool __cdecl XLSXSheet::GetNextCellInt(__int64 &)" (?GetNextCellInt@XLSXSheet@@QEAA_NAEA_J@Z) [D:\a\application\build\app.vcxproj]
main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_sheet_next_cell_float referenced in function "public: bool __cdecl XLSXSheet::GetNextCellFloat(double &)" (?GetNextCellFloat@XLSXSheet@@QEAA_NAEAN@Z) [D:\a\application\build\app.vcxproj]
main.obj : error LNK2019: unresolved external symbol __imp_xlsxioread_sheet_next_cell_datetime referenced in function "public: bool __cdecl XLSXSheet::GetNextCellDateTime(__int64 &)" (?GetNextCellDateTime@XLSXSheet@@QEAA_NAEA_J@Z) [D:\a\application\build\app.vcxproj]

D:\a\application\build\RelWithDebInfo\app.exe : 

fatal error LNK1120: 10 unresolved externals [D:\a\application\build\app.vcxproj]

I've seen https://github.com/brechtsanders/xlsxio/issues/70, but that's no solution, because when building statically a .def file is not created.

brechtsanders commented 2 years ago

Looks like you have a static build but the header file thinks you use the shared library. You can fix that by defining STATIC in your compiler flags.

jakoch commented 2 years ago

The issue is not resolved for me.

The dependencies are build with -DBUILD_SHARED_LIBS=OFF (from vcpkg's triplet x64-windows-static). My other dependencies are sqlite3 and curl. Both are statically linked and their symbols are found. The application is build with -DBUILD_SHARED_LIBS=OFF.

Would you be so nice to elaborate on how to that (define STATIC)?

brechtsanders commented 2 years ago

I'm not an MSVC expert, but I believe you just need to add /D STATIC to the compiler flags. When using cmake I suppose you can do that with -DCMAKE_C_FLAGS:STRING="/D STATIC" and/or -DCMAKE_CXX_FLAGS:STRING="/D STATIC".

jakoch commented 2 years ago

Ok, that works. Thank you.


Yes, one needs to define STATIC or BUILD_XLSXIO_STATIC. Referencing: https://github.com/brechtsanders/xlsxio/blob/master/include/xlsxio_read.h#L65

I'm including now like this:

#define BUILD_XLSXIO_STATIC
#include "xlsxio_read.h"
brechtsanders commented 2 years ago

Thats the ugly way to do it. If you want your source to be able to build to both static and shared you should really define STATIC somewhere in the build system, not in the code.

jakoch commented 2 years ago

Agreed, it's kind of ugly.

Maybe it's better to set this from my CMakeLists.txt:

if(BUILD_SHARED_LIBS)
   target_compile_definitions(app PRIVATE BUILD_XLSXIO_SHARED)
else()
   target_compile_definitions(app PRIVATE BUILD_XLSXIO_STATIC)
endif()
brechtsanders commented 2 years ago

No, don't define BUILD_XLSXIO_SHARED for the shared library, because that will define functions with dllexport instead of dllimport.

Only define BUILD_XLSXIO_STATIC for static builds, nothing for shared builds.

jakoch commented 2 years ago

Ok.. that brings me to:

if(NOT BUILD_SHARED_LIBS)
   target_compile_definitions(app PRIVATE BUILD_XLSXIO_STATIC)
endif()

Thank you!