Skip to content

Frame tests for loading shared objects for the emscripten build #548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 21, 2025

Conversation

anutosh491
Copy link
Collaborator

Description

Now that llvm/llvm-project#133037 has been merged, we should be able to test out loading shared libraries for the emscripten build.

Type of change

Please tick all options which are relevant.

  • Bug fix
  • New feature
  • Requires documentation updates

Testing

Please describe the test(s) that you added and ran to verify your changes.

Checklist

  • I have read the contribution guide recently

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

@mcbarton
Copy link
Collaborator

mcbarton commented Apr 2, 2025

@anutosh491 Just a couple of questions. Once this PR is ready will we be able to run the DynamicLibraryManagerTest Sanity test? Currently its skipped.

Does this PR have any relation to this PR? #308

@anutosh491
Copy link
Collaborator Author

Explaining the use-case/roadmap here

Symengine a Computer Algebra System with 1.2k stars wants us to host a link in their Readme so that users there can try it as a REPL in the browser. Check this

Steps to achieve this

  1. Add a milestone label for [clang-repl] Implement LoadDynamicLibrary for clang-repl wasm use cases llvm/llvm-project#133037 . I have already cherry picked the relevant commit. @vgvassilev should be able to help us out here.

  2. Move to llvm 20 (Upgrade CppInterOp to support llvm 20 #491)

  3. Take this PR in after any review involved (and probably make a release whenever we are happy)

  4. SymEngine used #pragma cling load back in the days to integrate with xeus-cling
    https://github.com/symengine/symengine/blob/master/symengine/symengine_config_cling.h.in#L5C1-L5C20

  5. We can add a similar file having something like

#include "clang/Interpreter/CppInterOp.h"
static bool _symengine_loaded = []() {
    Cpp::LoadLibrary(@SYMENGINE_CPPINTEROP_LIBRARY_PATH@);
    return true;
}();

Included when we build using these definitions #if defined(__CLANG_REPL__) && defined(__EMSCRIPTEN__)

Was able to get this working locally !!!

image

This involves only having symengine in our wasm environment and no explicit linking/loading from our side. Any symengine header included would also load libsymengine.so .

So to provide the link to symengine, we would just ask the maintainers to fork the template library (https://github.com/jupyterlite/xeus-lite-demo) under their symengine org (and probably ask them to name it Symengine/xeus-cpp-symengine-demo or whatever) . Here in the template they would just need to update the environment and add symengine to get the above working.

@anutosh491
Copy link
Collaborator Author

anutosh491 commented Apr 2, 2025

Once this PR is ready will we be able to run the DynamicLibraryManagerTest Sanity test?

Absolutely. This PR fixes that.

EDIT: Actually to be fair not the Sanity test. The sanity test is not catered to the emscripten build.But we shall be able to add a custom test suitable for the emscripten build just like what I added (look at the test I added in the pr)

The sanity test has

std::string BinaryPath = GetExecutablePath(/*Argv0=*/nullptr);
  llvm::StringRef Dir = llvm::sys::path::parent_path(BinaryPath);
  Cpp::AddSearchPath(Dir.str().c_str());

Things like llvm::sys etc would not work for emscripten. Also there is no real concept of search paths in wasm ( we know where the preload the shared lib in the MEMFS so we don't have to search for it )

Does this PR have any relation to this PR? #308

The library autoloader PR is not focusing on loading dynamic libs while building against emscripten (or basically for our wasm use case) as per my knowledge. So the idea might have some relation but the use case is different.

Copy link

codecov bot commented Apr 2, 2025

Codecov Report

Attention: Patch coverage is 28.57143% with 5 lines in your changes missing coverage. Please review.

Project coverage is 76.36%. Comparing base (03135b6) to head (c2dbd47).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
lib/Interpreter/CppInterOpInterpreter.h 28.57% 5 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #548      +/-   ##
==========================================
- Coverage   76.45%   76.36%   -0.10%     
==========================================
  Files           9        9              
  Lines        3648     3655       +7     
==========================================
+ Hits         2789     2791       +2     
- Misses        859      864       +5     
Files with missing lines Coverage Δ
lib/Interpreter/CppInterOpInterpreter.h 78.64% <28.57%> (-1.90%) ⬇️
Files with missing lines Coverage Δ
lib/Interpreter/CppInterOpInterpreter.h 78.64% <28.57%> (-1.90%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

@anutosh491 anutosh491 marked this pull request as ready for review May 12, 2025 03:51
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

@anutosh491
Copy link
Collaborator Author

Just in case, anyone would like to try this through lite.

  1. make a custom_module.cpp
#include <iostream>

extern "C" {
    void my_custom_function() {
        std::cout << "Hello from my_custom_function!" << std::endl;
    }
}

  1. compile it as a Side Module
emcc custom_module.cpp -s SIDE_MODULE=1 -O3 -o custom_module.so
  1. Load it through Jupyterlite UI at runtime (through the upload button at the left... shown by an arrow)
    Once you have it there, try using it
    image

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

@mcbarton
Copy link
Collaborator

Codecov Report

Attention: Patch coverage is 28.57143% with 5 lines in your changes missing coverage. Please review.

Project coverage is 76.28%. Comparing base (28ba16e) to head (54e0e14).

Files with missing lines Patch % Lines
lib/Interpreter/CppInterOpInterpreter.h 28.57% 5 Missing ⚠️
Additional details and impacted files
🚀 New features to boost your workflow:

The tests don't cover all the lines of the patch. Please fix this.

@anutosh491
Copy link
Collaborator Author

anutosh491 commented May 14, 2025

The tests don't cover all the lines of the patch. Please fix this.

Weird

  1. The support for loading shared libraries in llvm was added in llvm 20
  2. So if you see the test caters only to
TEST(DynamicLibraryManagerTest, BasicSymbolLookup) {
#ifndef EMSCRIPTEN
  GTEST_SKIP() << "This test is only intended for Emscripten builds.";
#else
  #if CLANG_VERSION_MAJOR < 20
    GTEST_SKIP() << "Support for loading shared libraries was added in LLVM 20.";
  #endif
#endif
  1. So the added test on any xx-xx-clang-rep-20-emscripten would only pass if it goes through the mechanism added.

I don't know how the above codecov report works but the test added is literally to address this :)

EDIT : Hmmm, I see the codecov/patch && codecov/project fail even before the emscripten test is run ( the emscripten builds were going on and these jobs already failed)

EDIT 2 : This should confirm the those patches are tested http://github.com/compiler-research/CppInterOp/actions/runs/15027746990/job/42232690523?pr=548#step:9:708

@mcbarton
Copy link
Collaborator

mcbarton commented May 14, 2025

The tests don't cover all the lines of the patch. Please fix this.

Weird

  1. The support for loading shared libraries in llvm was added in llvm 20
  2. So if you see the test caters only to
TEST(DynamicLibraryManagerTest, BasicSymbolLookup) {
#ifndef EMSCRIPTEN
  GTEST_SKIP() << "This test is only intended for Emscripten builds.";
#else
  #if CLANG_VERSION_MAJOR < 20
    GTEST_SKIP() << "Support for loading shared libraries was added in LLVM 20.";
  #endif
#endif
  1. So the added test on any xx-xx-clang-rep-20-emscripten would only pass if it goes through the mechanism added.

I don't know how the above codecov report works but the test added is literally to address this :)

Just had a look and this seems to be a result of us moving away from ifdef __EMSCRIPTEN__ . Given the codecov is run on a native platform it won't ever be able test triple.isWasm() == true . @vgvassilev can decide what to do with that information is his review

image

We probably need some way to have code coverage number for Emscripten if possible, but that is another issue to this PR entirely.

@anutosh491
Copy link
Collaborator Author

anutosh491 commented May 14, 2025

it won't ever be able test triple.isWasm() == true

Arghh, I thought using target opts here is a more organic solution but if we can't then probably we can't :\
(should codecov be respected in every case ? if yes, can we somehow skip it for patches we know shouldn't be covered)

@anutosh491
Copy link
Collaborator Author

Hey @vgvassilev

The other day I addressed your reviews here but we see this after I got rid of the hardcoding.

#548 (comment)

To which I make this comment #548 (comment) saying what you suggested seems the organic way to get this but it might not be covered through codecov.

Let us know what you think !

Copy link
Contributor

@vgvassilev vgvassilev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@vgvassilev
Copy link
Contributor

The tests don't cover all the lines of the patch. Please fix this.

Weird

  1. The support for loading shared libraries in llvm was added in llvm 20
  2. So if you see the test caters only to
TEST(DynamicLibraryManagerTest, BasicSymbolLookup) {
#ifndef EMSCRIPTEN
  GTEST_SKIP() << "This test is only intended for Emscripten builds.";
#else
  #if CLANG_VERSION_MAJOR < 20
    GTEST_SKIP() << "Support for loading shared libraries was added in LLVM 20.";
  #endif
#endif
  1. So the added test on any xx-xx-clang-rep-20-emscripten would only pass if it goes through the mechanism added.

I don't know how the above codecov report works but the test added is literally to address this :)

Just had a look and this seems to be a result of us moving away from ifdef __EMSCRIPTEN__ . Given the codecov is run on a native platform it won't ever be able test triple.isWasm() == true . @vgvassilev can decide what to do with that information is his review

image

We probably need some way to have code coverage number for Emscripten if possible, but that is another issue to this PR entirely.

We should move away from that hardcoding but in a separate PR that covers the tests.

@anutosh491 anutosh491 merged commit 6951212 into compiler-research:main May 21, 2025
72 of 74 checks passed
@anutosh491 anutosh491 deleted the shared_libs branch May 21, 2025 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants