Skip to content
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

WCLAP with Emscripten #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,23 @@ option(COPY_AFTER_BUILD "Copy the clap to ~/Library on MACOS, ~/.clap on linux"

add_subdirectory(libs/clap EXCLUDE_FROM_ALL)

add_library(${PROJECT_NAME} MODULE
if(EMSCRIPTEN)
add_executable(${PROJECT_NAME}
src/clap-c99-distortion.c)
else()
add_library(${PROJECT_NAME} MODULE
src/clap-c99-distortion.c)
endif()
target_link_libraries(${PROJECT_NAME} clap-core)

if(APPLE)
if(EMSCRIPTEN)
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-O3 -ffast-math -fno-exceptions -fno-rtti")
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-O3 -ffast-math -fno-exceptions -fno-rtti -sSTANDALONE_WASM --no-entry -sEXPORTED_FUNCTIONS=_clap_entry,_malloc -s INITIAL_MEMORY=512kb -sALLOW_MEMORY_GROWTH -sALLOW_TABLE_GROWTH -sPURE_WASI --export-table")
Copy link
Owner

Choose a reason for hiding this comment

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

So build type release and debug don’t do this in emscripten?

winder if we want an wclap.cmake with utilities?

I’m happy to merge this if you want tho

Copy link
Author

@geraintluff geraintluff Nov 23, 2024

Choose a reason for hiding this comment

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

Maybe they'd do -O3. The others (-ffast-math -fno-exceptions -fno-rtti) are my personal defaults, and should probably be removed to avoid confusion.

I previously couldn't get Release builds to work properly in a non-Emscripten project, but that's more about me being bad at CMake. 😅 If you want to refactor/rewrite this into something neater, that'd be fine by me!

Copy link
Author

@geraintluff geraintluff Nov 23, 2024

Choose a reason for hiding this comment

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

To explain the other linker options:

  • -sSTANDALONE_WASM: this can probably be omitted - it's the default when generating a .wasm anyway (with no JS loader), and is also implied by -sPURE_WASI.
  • --no-entry: don't expect a main()
  • -sEXPORTED_FUNCTIONS=_clap_entry,_malloc: not sure what the _ prefix is about. We obviously need clap_entry (which is a pointer rather than a function, but that's just this flag being badly named). We also need malloc because the in order to pass in pointers to host structs, those structs need to be inside the memory WASM can see. This doesn't have to be the real malloc() though - just any function that the host can use to get some memory it knows the plugin isn't using for anything else.
  • -s INITIAL_MEMORY=512kb -sALLOW_MEMORY_GROWTH: The default is 16Mb with no memory growth. This is neater and feels more flexible (to me), but optional.
  • -sALLOW_TABLE_GROWTH --export-table: WASM functions aren't addressed by memory locations, but by indices in a "function table". Function pointers are integer indices into this table. In order for our host-owned structs to point to host-defined functions, the WASM module needs to (1) export this function table so it's visible, and (2) allow it to grow, so we can expand it and insert our host functions in there.
  • -sPURE_WASI: This disables the last piece of (fairly pointless) Emscripten magic. Without this, Emscripten adds an extra import function (emscripten_notify_memory_growth) which gets called when the memory expands.


set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.wclap/")
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME module) # call it module.wasm
set(CMAKE_EXECUTABLE_SUFFIX ".wasm") # No accompanying JS
elseif(APPLE)
set_target_properties(${PROJECT_NAME} PROPERTIES
BUNDLE True
BUNDLE_EXTENSION clap
Expand Down