Skip to content

Instantly share code, notes, and snippets.

@ochafik
Created July 8, 2024 22:32
Show Gist options
  • Select an option

  • Save ochafik/ecd7b6412dfe710aa9de7648696912cf to your computer and use it in GitHub Desktop.

Select an option

Save ochafik/ecd7b6412dfe710aa9de7648696912cf to your computer and use it in GitHub Desktop.
Ideal Emscripten CMakeFile.txt
../../emsdk/emsdk activate
source "../../emsdk/emsdk_env.sh"

for p in OFF ON ; do
  for t in Debug Release ; do
    rm -fR build && \
      emcmake cmake -B build \
        -DWASM_BUILD_TYPE=node \
        -DWASM_PTHREAD=$p \
        -DCMAKE_BUILD_TYPE=$t && \
      cmake --build build && \
      node build/minicat.js CMakeLists.txt || say "failed with $t p=$p"
  done
done

emcmake cmake -B build -DWASM_BUILD_TYPE=node && cmake --build build &&  node build/minicat.js CMakeLists.txt
cmake_minimum_required(VERSION 3.29)
project(zenfs-test LANGUAGES CXX)
set(WASM_BUILD_TYPE "web" CACHE STRING "WebAssembly build type. Support web or node")
option(WASM_PTHREAD "Whether to build WASM w/ pthread" OFF)
add_executable(minicat minicat.cc)
target_compile_options(minicat PRIVATE "$<$<CONFIG:DEBUG>:-DDEBUG>")
set_property(TARGET minicat PROPERTY CXX_STANDARD 17)
set_property(TARGET minicat PROPERTY CXX_EXTENSIONS OFF)
set_property(TARGET minicat PROPERTY CXX_STANDARD_REQUIRED ON)
# Output compilation database (compile_commands.json), so we can e.g. run clang-tidy or other tools separately
set_property(TARGET minicat PROPERTY EXPORT_COMPILE_COMMANDS ON)
set_property(TARGET minicat PROPERTY LINKER_LANGUAGE CXX)
if (CMAKE_SYSTEM_NAME STREQUAL Emscripten)
# https://emscripten.org/docs/tools_reference/emcc.html
target_compile_options(minicat PRIVATE
-fexceptions
)
target_link_options(minicat PUBLIC
# https://emscripten.org/docs/tools_reference/settings_reference.html
-fexceptions
-sABORT_ON_WASM_EXCEPTIONS
-sALLOW_MEMORY_GROWTH=1
-sDISABLE_EXCEPTION_CATCHING=0
-sEXPORTED_RUNTIME_METHODS=['FS','ENV','PATH','callMain','formatException','ERRNO_CODES']
-sFORCE_FILESYSTEM=1
-sMAXIMUM_MEMORY=4GB
$<$<CONFIG:Debug>:
-g3
-gsource-map
-O0
-sASSERTIONS=2
-sCHECK_NULL_WRITES
-sEXCEPTION_DEBUG
-sLOAD_SOURCE_MAP
-sSAFE_HEAP=1
-sSTACK_OVERFLOW_CHECK=2
# -sMALLOC=emmalloc-memvalidate # Broken?
-sSTRICT # Broken?
>
)
if (WASM_PTHREAD)
target_compile_options(minicat PRIVATE -pthread)
target_link_options(minicat PUBLIC -pthread)
endif()
if (WASM_BUILD_TYPE STREQUAL "web")
target_link_options(minicat PUBLIC
-sENVIRONMENT=web,worker
-sEXIT_RUNTIME=1
-sEXPORT_ES6=1
-sEXPORT_NAME=minicat
-sMODULARIZE=1
)
elseif (WASM_BUILD_TYPE STREQUAL "node")
target_link_options(minicat PUBLIC
-sENVIRONMENT=node,worker
-sNODEJS_CATCH_EXIT
-sNODERAWFS
# Single-file release FTW:
$<$<CONFIG:Release>:-sSINGLE_FILE> # Takes more space so only doing this for node.js build
# Alternatively, code caching would make things faster:
# -sNODE_CODE_CACHING -sWASM_ASYNC_COMPILATION=0
)
else()
message(FATAL_ERROR "Invalid WASM_BUILD_TYPE: ${WASM_BUILD_TYPE} (allowed: node, web)")
endif()
endif()
// Minimalistic cat C++ implementation
#include <iostream>
#include <fstream>
int main(int argc, char *argv[]) {
// Disable buffering
std::cout.setf(std::ios::unitbuf);
// No arguments -> copy stdin
if (argc == 1) {
char c;
while (std::cin.get(c)) std::cout << c;
return 0;
}
for (int i = 1; i < argc; i++) {
std::ifstream file(argv[i]);
if (!file.is_open()) {
std::cerr << "Error: Could not open file " << argv[i] << std::endl;
return 1;
}
char c;
while (file.get(c)) std::cout << c;
file.close();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment