Skip to content

SHARED / dynamic library with CMake #15276

Closed

Description

@DerThorsten

Hi,
I have a question wrt shared / dynamic linking.
While I can successful generated a shared library with emscripten when I use no build system with smth like

em++ -c -fpic package_a/a.cpp -s SIDE_MODULE=1 -s EXPORT_ALL=1  -s LLD_REPORT_UNDEFINED -Ipackage_a -shared -o liba.wasm

I cannot make cmake generate a shared / dynamic library.
I try to pass the required SIDE_MODULE flag via target_compile_options / target_link_options but I still get the error message that the the target platform does not support dynamic linking.

    add_library(${name} SHARED ${ALL_FILES})
    SET(EMS_OPTS "-s SIDE_MODULE=1 -shared -s EXPORT_ALL=1 ")
    target_compile_options(${name}  PUBLIC ${EMS_OPTS})
    target_link_options(${name}     PUBLIC ${EMS_OPTS})
  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.

I know that static libraries are recommended but I try to compile LLVM / clang / cling itself for emscripten and I need support for dlopen.
When I compile everything with static linking I do not get support for dlopen and get error messages when I use the generated code.

Is there any minimal example how to generate shared libs from cmake?

Activity

  1. changed the title [-]SHARED library with Cmake[/-] [+]SHARED library with CMake[/+] on Oct 11, 2021
  2. changed the title [-]SHARED library with CMake[/-] [+]SHARED / dynamic library with CMake[/+] on Oct 11, 2021
  3. DerThorsten commented on Oct 11, 2021

    @DerThorsten
    Author

    the error I see when I compile everything as static as possible is:

    
    RuntimeError: abort(RuntimeError: abort(To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking).
    
    
  4. DerThorsten commented on Oct 11, 2021

    @DerThorsten
    Author

    besides this issue cling builds like a charm.
    The overall goal here is to make this interactive c++ jupyter kernel run in jupyterlite
    This might be the last tiny issue to get this running in the browser

  5. kripken commented on Oct 11, 2021

    @kripken
    Member

    You can build with something like cmake -G Ninja and then ninja -v to get logging of the commands emitted. Likely it is not passing the link flag somehow. CMake can be pretty confusing there...

    For a working example of passing such flags, binaryen's CMakeLists.txt might be helpful. Here is a flag:

    https://github.com/WebAssembly/binaryen/blob/072c60c9314ca37f0f4a9393bb81dabd1be5a6b5/CMakeLists.txt#L272

    And here is the helper function:

    https://github.com/WebAssembly/binaryen/blob/072c60c9314ca37f0f4a9393bb81dabd1be5a6b5/CMakeLists.txt#L71-L76

  6. DerThorsten commented on Oct 12, 2021

    @DerThorsten
    Author

    thank you very much, it seems to work indeed when I pass the flags as shown above.
    It gets a bit trickier in this way to have different link flags for different targets (ie SIDE_MODULE vs MAIN_MODULE) but I can live with that.
    Thanks for the fast answer and this awesome project!

  7. sbc100 commented on Oct 13, 2021

    @sbc100
    Collaborator

    I'm pretty sure you can configure llvm to avoid depending on dlopen. It doesn't seem like it should be an essentail part of clang or llvm. You should be able build a fully statistically linked version.

  8. DerThorsten commented on Oct 14, 2021

    @DerThorsten
    Author

    @sbc100 It would be awesome to get ride of the dlopen.
    I tried to set all the related things here to 0 https://github.com/llvm-mirror/llvm/blob/2c4ca6832fa6b306ee6a7010bfb80a3f2596f824/include/llvm/Config/config.h.cmake#L50
    and I even removed all intannces of dlopen etc from the codebase.
    Btw my overall goal is to get cling running.
    Not yet 100 % if the problem comes from clang or cling.

    If you have any hints, I would be super thankfull.
    Having cling in the browser would be an awesome feature for https://jupyterlite.readthedocs.io/en/latest/ (ie a in browser version of jupyter / https://github.com/jupyter-xeus/xeus-cling )

  9. sbc100 commented on Oct 14, 2021

    @sbc100
    Collaborator

    One thing you can try is adding -Wl,--trace-symbol=dlopen. This will tell you why the dlopen symbol is getting included in the final link.

    Another approach would be to remove these stub functions:

    _dlopen_js: function(filename, flag) {
    abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking");
    },
    _emscripten_dlopen_js: function(filename, flags, user_data, onsuccess, onerror) {
    abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking");
    },
    _dlsym_js: function(handle, symbol) {
    abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking");
    },

    That way you will get a link error instead of a compile error when attempting to include dlopen.

  10. DerThorsten commented on Oct 14, 2021

    @DerThorsten
    Author

    will give this a try as soon as I can, thanks for the hints! very much appreciated!

  11. hoodmane commented on Oct 19, 2021

    @hoodmane
    Collaborator

    I am running into the same problem with Pyodide trying to build geos. We really do want to dynamically link geos, static linking is not an option. How do we get CMake to work? Should I open a separate issue?

  12. hoodmane commented on Oct 19, 2021

    @hoodmane
    Collaborator

    I tried adding set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) to the beginning of CMakeLists but this had no effect.

  13. ax3l commented on Feb 14, 2022

    @ax3l

    I think I found a way how we can overwrite this manually:
    https://cmake.org/pipermail/cmake/2018-December/068771.html

    # CLI
    ... -DCMAKE_PROJECT_INCLUDE=overwriteProp.cmake
    # overwriteProp.cmake
    set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
    set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-s SIDE_MODULE=1")
    set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-s SIDE_MODULE=1")
    set(CMAKE_STRIP FALSE)  # used by default in pybind11 on .so modules

    Used in: pyodide/pyodide#2169

  14. added a commit that references this issue on Jan 1, 2025
  15. added a commit that references this issue on Jan 20, 2025
  16. added a commit that references this issue on Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions