You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
CMake in version 1.38.31+ getting unresolved externals for static linking with libraries #8598
CMake in version 1.38.31+ getting unresolved externals for static linking. I use CMake to build my emscripten project. In older version 1.38.30 it worked correctly but when I upgraded to 1.38.31 I get unresolved externals for code inside of static libraries I link against. If I replace the files in cmake/Modules with the older version(1.38.30) it works. Looks like a regression bug?
changed the title [-]CMake in version 1.38.31+ getting unresolved externals for static linking[/-][+]CMake in version 1.38.31+ getting unresolved externals for static linking with libraries[/+]on May 13, 2019
The addition of this flag which tells cmake we don't support shared libraries. Which technically we don't (at least not in the normal .so sense).
Can you elaborate more on your error or use case? Or find a repro case? Were you somehow previously relying on shared libraries being reported as supported?
When using CMake and building in version 1.38.31 it warns I should use STATIC instead of SHARED but even with this is changed it still gets an unresolved external. Using STATIC instead of SHARED generates an unresolved external in 1.38.30.
Here are the command line errors. I am using CMake to generate a ninja build.
error: undefined symbol: compress2
error: undefined symbol: jpeg_CreateCompress
error: undefined symbol: jpeg_destroy_compress
error: undefined symbol: jpeg_finish_compress
error: undefined symbol: jpeg_set_defaults
error: undefined symbol: jpeg_set_quality
error: undefined symbol: jpeg_start_compress
error: undefined symbol: jpeg_std_error
error: undefined symbol: jpeg_stdio_dest
error: undefined symbol: jpeg_write_scanlines
I also get these warnings which is new with 1.38.31+
CMake Warning (dev) at D:/tfs/Main/SRC/Common/3DEngine/Trunk/ThirdParty/jpeg-8d/CMakeLists.txt:80 (add_library):
ADD_LIBRARY called with SHARED option but the target platform does not
support dynamic linking. Building a STATIC library instead. This may lead
to problems.
This warning is for project developers. Use -Wno-dev to suppress it.
Looks like the binary your building is not being linked against libjpeg or zlib. When building for emscripten you should run cmake -DBUILD_SHARED_LIBS=OFF and ensure that your cmake files honor this setting by building static, and not dynamic libraries.
BTW, I still don't see the failing link command, does in include libjpeg or libz anywhere?
In pre 1.38.31 you could build SHARED libraries that pull in all STATIC library dependencies and there would only be a warning about changing the file name (which disappears if change the suffix):
emcc:WARNING: When Emscripten compiles to a typical native suffix for shared libraries (.so, .dylib, .dll) then it emits an LLVM bitcode file. You should then compile that to an emscripten SIDE_MODULE (using that flag) with suffix .wasm (for wasm) or .js (for asm.js). (You may also want to adapt your build system to emit the more standard suffix for a file with LLVM bitcode, '.bc', which would avoid this warning.)
I guess the library you have been trying to link was a shared one that depends on libjpeg or so.
@sbc100 Is there an alternative to SHARED in 1.38.31? I understand that you cannot build truly shared libraries yet, but keeping the linking functionality around would be useful.
OK, I guess there was some use case for the fake shared library support. We can consider reverting back to the old behaviour.
Emscripten does not support shared libraries as such. It supports SIDE_MODULE and MAIN_MODULE, but they are quite different to normal shared libraries. The relevant difference here is that you can't pass a SIDE_MODULE on the command line like you can with a shared library.
Since we don't support shared libraries is seemed better not to pretend that we did.
Can I ask you about your use case:
Is the library you are building actually used dynamically in your app? (i.e. do you like it as a SIDE_MODULE later?)
Is there any reason you cannot switch using static libraries? (Normally done via -DBUILD_SHARED_LIBS=OFF)
Is the library in question open source so I can take a look, it would be good for me to see exactly how your use case works.
If I do, the produced .bc will not include libraries I linked against in CMake. Otherwise there is no reason right now, no.
I'm afraid it's not open source, but what we are doing is having protobuf as a third party library (via add_subdirectory) and link against it (libprotobuf).
To fix it temporarily, I added an extra step that extracts all the object files from the main library and all its dependencies and puts them together manually.
Do you mean that your generted library file doesn't include its library dependencies? That is what i would expect and this is normal for static linking, no? With static linking you need to do -lfoo and -lfoo_depenenency when you your final link. With dynamic linking you only need to do -lfoo.
I guess our previous "fake" dynamic linking was allowing is to get the benefit to only specifying -lfoo because foo contains a copy of all its dependencies too. I'd rather have developers use the normal static linking appraoches until we have real dynamic linking.. but I'm prepared to be swayed on this point if enough people say the previous hacks were useful to them.
I have the same problem, what is the proper solution to this? My project is a bunch of .a files normally, but I guess a workaround is used with the .so stuff. Can i specify to emscripten to include all .a files?
This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 30 days. Feel free to re-open at any time if this issue is still relevant.
Activity
[-]CMake in version 1.38.31+ getting unresolved externals for static linking[/-][+]CMake in version 1.38.31+ getting unresolved externals for static linking with libraries[/+]sbc100 commentedon May 13, 2019
Looks like the only change to those files in that range was #8362. i.e:
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)The addition of this flag which tells cmake we don't support shared libraries. Which technically we don't (at least not in the normal
.sosense).Can you elaborate more on your error or use case? Or find a repro case? Were you somehow previously relying on shared libraries being reported as supported?
briangavin commentedon May 14, 2019
In my application I try to link libjpeg which is compiled as a static libary and linked with my application.
Here is a simplified version of my application.
libjpeg Cmake file
CMakeLists_LIBJPEG.txt
Pseudo version of Main App that links against libjpeg
CMakeLists_MainAPP.txt
When using CMake and building in version 1.38.31 it warns I should use STATIC instead of SHARED but even with this is changed it still gets an unresolved external. Using STATIC instead of SHARED generates an unresolved external in 1.38.30.
sbc100 commentedon May 14, 2019
What are the unresovled symbols? Where should they be defined?
sbc100 commentedon May 14, 2019
Can you include the failing command line and the error it produces?
briangavin commentedon May 14, 2019
Here are the command line errors. I am using CMake to generate a ninja build.
error: undefined symbol: compress2
error: undefined symbol: jpeg_CreateCompress
error: undefined symbol: jpeg_destroy_compress
error: undefined symbol: jpeg_finish_compress
error: undefined symbol: jpeg_set_defaults
error: undefined symbol: jpeg_set_quality
error: undefined symbol: jpeg_start_compress
error: undefined symbol: jpeg_std_error
error: undefined symbol: jpeg_stdio_dest
error: undefined symbol: jpeg_write_scanlines
I also get these warnings which is new with 1.38.31+
CMake Warning (dev) at D:/tfs/Main/SRC/Common/3DEngine/Trunk/ThirdParty/jpeg-8d/CMakeLists.txt:80 (add_library):
ADD_LIBRARY called with SHARED option but the target platform does not
support dynamic linking. Building a STATIC library instead. This may lead
to problems.
This warning is for project developers. Use -Wno-dev to suppress it.
sbc100 commentedon May 14, 2019
Looks like the binary your building is not being linked against libjpeg or zlib. When building for emscripten you should run cmake
-DBUILD_SHARED_LIBS=OFFand ensure that your cmake files honor this setting by building static, and not dynamic libraries.BTW, I still don't see the failing link command, does in include libjpeg or libz anywhere?
hpohl commentedon May 22, 2019
Just ran into the same thing.
In pre 1.38.31 you could build
SHAREDlibraries that pull in allSTATIClibrary dependencies and there would only be a warning about changing the file name (which disappears if change the suffix):I guess the library you have been trying to link was a shared one that depends on
libjpegor so.@sbc100 Is there an alternative to
SHAREDin 1.38.31? I understand that you cannot build truly shared libraries yet, but keeping the linking functionality around would be useful.sbc100 commentedon May 23, 2019
OK, I guess there was some use case for the fake shared library support. We can consider reverting back to the old behaviour.
Emscripten does not support shared libraries as such. It supports SIDE_MODULE and MAIN_MODULE, but they are quite different to normal shared libraries. The relevant difference here is that you can't pass a SIDE_MODULE on the command line like you can with a shared library.
Since we don't support shared libraries is seemed better not to pretend that we did.
Can I ask you about your use case:
-DBUILD_SHARED_LIBS=OFF)hpohl commentedon May 23, 2019
add_subdirectory) and link against it (libprotobuf).To fix it temporarily, I added an extra step that extracts all the object files from the main library and all its dependencies and puts them together manually.
sbc100 commentedon May 23, 2019
Do you mean that your generted library file doesn't include its library dependencies? That is what i would expect and this is normal for static linking, no? With static linking you need to do
-lfooand-lfoo_depenenencywhen you your final link. With dynamic linking you only need to do-lfoo.I guess our previous "fake" dynamic linking was allowing is to get the benefit to only specifying
-lfoobecausefoocontains a copy of all its dependencies too. I'd rather have developers use the normal static linking appraoches until we have real dynamic linking.. but I'm prepared to be swayed on this point if enough people say the previous hacks were useful to them.hpohl commentedon May 23, 2019
That is correct. I only used it for "bundling". And I guess @briangavin did too.
briangavin commentedon May 27, 2019
I tried adding -DBUILD_SHARED_LIBS=OFF and it did not help attached is a simple test case of the problem.
EMTest.zip
JDaance commentedon Oct 2, 2019
I have the same problem, what is the proper solution to this? My project is a bunch of .a files normally, but I guess a workaround is used with the .so stuff. Can i specify to emscripten to include all .a files?
kripken commentedon Oct 2, 2019
@sbc100 may have a better idea, but using
-s LINKABLEwould force all.acontents to be included, I believe.stale commentedon Oct 7, 2020
This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 30 days. Feel free to re-open at any time if this issue is still relevant.