From 11da083507b19b603ef9c99fce209ca49258d873 Mon Sep 17 00:00:00 2001 From: "Hochsteger, Matthias" Date: Fri, 28 Jul 2023 13:01:41 +0200 Subject: [PATCH] Emscripten support --- CMakeLists.txt | 6 ++--- cmake/SuperBuild.cmake | 20 ++++++++++++---- libsrc/core/CMakeLists.txt | 7 ++++++ libsrc/core/exception.cpp | 4 ++-- libsrc/core/utils.hpp | 2 ++ libsrc/meshing/meshclass.cpp | 44 ++++++++++++++++++------------------ nglib/CMakeLists.txt | 6 +++++ rules/CMakeLists.txt | 12 ++++++++-- 8 files changed, 67 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86fafa9a..bde4fef4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,7 +95,7 @@ if(USE_PYTHON) file(TO_CMAKE_PATH ${PYTHON_PACKAGES_INSTALL_DIR} PYTHON_PACKAGES_INSTALL_DIR) endif(USE_PYTHON) -if(APPLE) +if(APPLE AND NOT EMSCRIPTEN) set(NG_INSTALL_DIR_BIN_DEFAULT Contents/MacOS) set(NG_INSTALL_DIR_LIB_DEFAULT Contents/MacOS) set(NG_INSTALL_DIR_CMAKE_DEFAULT Contents/Resources/CMake) @@ -104,7 +104,7 @@ if(APPLE) set(NG_INSTALL_DIR_INCLUDE_DEFAULT Contents/Resources/include) set(NG_RPATH_TOKEN "@loader_path") -else(APPLE) +else(APPLE AND NOT EMSCRIPTEN) set(NG_INSTALL_DIR_BIN_DEFAULT bin) set(NG_INSTALL_DIR_LIB_DEFAULT lib) if(WIN32) @@ -117,7 +117,7 @@ else(APPLE) set(NG_INSTALL_DIR_INCLUDE_DEFAULT include) set(NG_RPATH_TOKEN "\$ORIGIN") -endif(APPLE) +endif(APPLE AND NOT EMSCRIPTEN) set(NG_INSTALL_DIR_PYTHON ${NG_INSTALL_DIR_PYTHON_DEFAULT} CACHE STRING "Install directory for Python files") set(NG_INSTALL_DIR_BIN ${NG_INSTALL_DIR_BIN_DEFAULT} CACHE STRING "Install directory for executables") diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index 5a72b6ca..091b2477 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -14,9 +14,16 @@ set (SUBPROJECT_ARGS PREFIX ${CMAKE_CURRENT_BINARY_DIR}/dependencies ) +if (EMSCRIPTEN) + set (SUBPROJECT_ARGS + ${SUBPROJECT_ARGS} + CMAKE_COMMAND emcmake ${CMAKE_COMMAND}) +endif() + # only show output on failure in ci-builds if(DEFINED ENV{CI}) set (SUBPROJECT_ARGS + ${SUBPROJECT_ARGS} LOG_DOWNLOAD ON LOG_BUILD ON LOG_INSTALL ON @@ -134,25 +141,27 @@ endif(BUILD_OCC) endif(USE_OCC) if(BUILD_ZLIB) - set(ZLIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/dependencies/zlib) + set(ZLIB_ROOT ${CMAKE_CURRENT_BINARY_DIR}/dependencies/zlib) ExternalProject_Add(project_zlib ${SUBPROJECT_ARGS} URL https://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip URL_MD5 9d6a627693163bbbf3f26403a3a0b0b1 DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external_dependencies CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX=${ZLIB_DIR} + -DCMAKE_INSTALL_PREFIX=${ZLIB_ROOT} ${SUBPROJECT_CMAKE_ARGS} UPDATE_COMMAND "" # Disable update BUILD_IN_SOURCE 1 ) list(APPEND NETGEN_DEPENDENCIES project_zlib) - list(APPEND NETGEN_CMAKE_PREFIX_PATH ${ZLIB_DIR}) if(WIN32) # force linking the static library - set(ZLIB_INCLUDE_DIRS ${ZLIB_DIR}/include) - set(ZLIB_LIBRARIES ${ZLIB_DIR}/lib/zlibstatic.lib) + set(ZLIB_INCLUDE_DIRS ${ZLIB_ROOT}/include) + set(ZLIB_LIBRARIES ${ZLIB_ROOT}/lib/zlibstatic.lib) + elseif(EMSCRIPTEN) + set(ZLIB_INCLUDE_DIRS ${ZLIB_ROOT}/include) + set(ZLIB_LIBRARIES ${ZLIB_ROOT}/lib/libz.a) endif(WIN32) else() include(cmake/external_projects/zlib.cmake) @@ -252,6 +261,7 @@ set_vars( NETGEN_CMAKE_ARGS OpenCascade_ROOT ZLIB_INCLUDE_DIRS ZLIB_LIBRARIES + ZLIB_ROOT NGLIB_LIBRARY_TYPE NGCORE_LIBRARY_TYPE diff --git a/libsrc/core/CMakeLists.txt b/libsrc/core/CMakeLists.txt index c4f4795e..3c1ca8ea 100644 --- a/libsrc/core/CMakeLists.txt +++ b/libsrc/core/CMakeLists.txt @@ -17,6 +17,13 @@ add_library(ngcore ${NGCORE_LIBRARY_TYPE} string(REPLACE "|" ";" ng_compile_flags_replace_sep "${NG_COMPILE_FLAGS}") target_compile_options(ngcore PUBLIC ${ng_compile_flags_replace_sep}) +if(EMSCRIPTEN) + target_link_options(ngcore PUBLIC -sALLOW_MEMORY_GROWTH) + # target_link_options(ngcore PUBLIC -sINITIAL_MEMORY=1gb) + target_link_options(ngcore PUBLIC -pthread -sPTHREAD_POOL_SIZE=16) + target_compile_options(ngcore PUBLIC -pthread) +endif() + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9) target_link_libraries(ngcore PUBLIC stdc++fs) endif() diff --git a/libsrc/core/exception.cpp b/libsrc/core/exception.cpp index b89d721e..38e6e62a 100644 --- a/libsrc/core/exception.cpp +++ b/libsrc/core/exception.cpp @@ -23,7 +23,7 @@ namespace ngcore // ********* STUFF FOR GETBACKTRACE *************************** -#ifdef __GNUC__ +#if defined __GNUC__ && !defined __EMSCRIPTEN__ #include #include @@ -226,7 +226,7 @@ static bool dummy = []() return true; }(); -#else // __GNUC__ +#else // __GNUC__ and not __EMSCRIPTEN__ namespace ngcore { diff --git a/libsrc/core/utils.hpp b/libsrc/core/utils.hpp index 4f37795c..210ba738 100644 --- a/libsrc/core/utils.hpp +++ b/libsrc/core/utils.hpp @@ -71,6 +71,8 @@ namespace ngcore unsigned long long tics; __asm __volatile("mrs %0, CNTVCT_EL0" : "=&r" (tics)); return tics; +#elif defined(__EMSCRIPTEN__) + return std::chrono::high_resolution_clock::now().time_since_epoch().count(); #else #warning "Unsupported CPU architecture" return 0; diff --git a/libsrc/meshing/meshclass.cpp b/libsrc/meshing/meshclass.cpp index 51e6017d..26d6c415 100644 --- a/libsrc/meshing/meshclass.cpp +++ b/libsrc/meshing/meshclass.cpp @@ -4452,30 +4452,30 @@ namespace netgen } return 1; - if ( /* hp */ 1) // needed for old, simple hp-refinement - { - // trigs with 2 or more segments are illegal - int i; - int nseg = 0; + // if ( /* hp */ 1) // needed for old, simple hp-refinement + // { + // // trigs with 2 or more segments are illegal + // int i; + // int nseg = 0; - if (!segmentht) - { - cerr << "no segmentht allocated" << endl; - return 0; - } + // if (!segmentht) + // { + // cerr << "no segmentht allocated" << endl; + // return 0; + // } - // Point3d cp(0.5, 0.5, 0.5); - for (i = 1; i <= 3; i++) - { - INDEX_2 i2(el.PNumMod (i), el.PNumMod (i+1)); - i2.Sort(); - if (segmentht -> Used (i2)) - nseg++; - } - if (nseg >= 2) - return 0; - } - return 1; + // // Point3d cp(0.5, 0.5, 0.5); + // for (i = 1; i <= 3; i++) + // { + // INDEX_2 i2(el.PNumMod (i), el.PNumMod (i+1)); + // i2.Sort(); + // if (segmentht -> Used (i2)) + // nseg++; + // } + // if (nseg >= 2) + // return 0; + // } + // return 1; } double Mesh :: CalcTotalBad (const MeshingParameters & mp ) diff --git a/nglib/CMakeLists.txt b/nglib/CMakeLists.txt index 370b670b..388d522d 100644 --- a/nglib/CMakeLists.txt +++ b/nglib/CMakeLists.txt @@ -9,5 +9,11 @@ target_link_libraries(nglib PUBLIC ngcore) target_link_libraries( nglib PRIVATE ${MPI_CXX_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${JPEG_LIBRARIES} ${MKL_LIBRARIES} ${ZLIB_LIBRARIES} ${OCC_LIBRARIES} netgen_cgns ) +if(EMSCRIPTEN) + target_link_options(nglib PUBLIC -sALLOW_MEMORY_GROWTH) + target_link_options(nglib PUBLIC -pthread -sPTHREAD_POOL_SIZE=16) + target_compile_options(nglib PUBLIC -pthread) +endif(EMSCRIPTEN) + install(TARGETS nglib netgen_cgns ${NG_INSTALL_DIR}) install(FILES nglib.h DESTINATION ${NG_INSTALL_DIR_INCLUDE} COMPONENT netgen_devel) diff --git a/rules/CMakeLists.txt b/rules/CMakeLists.txt index 82dad7e7..2c281ca3 100644 --- a/rules/CMakeLists.txt +++ b/rules/CMakeLists.txt @@ -1,7 +1,15 @@ # this file is included from the parent directory (otherwise generated source files are not recognized properly by cmake) # generate .cpp files containing the string of the .rls meshing rule files -add_executable(makerls rules/makerlsfile.cpp) +if(EMSCRIPTEN) + add_custom_command(OUTPUT makerls + COMMAND g++ ${CMAKE_CURRENT_SOURCE_DIR}/rules/makerlsfile.cpp -o ${CMAKE_CURRENT_BINARY_DIR}/makerls + ) + set(rules_command ${CMAKE_BINARY_DIR}/makerls) +else(EMSCRIPTEN) + add_executable(makerls rules/makerlsfile.cpp) + set(rules_command makerls) +endif() set(rules hexrules @@ -21,7 +29,7 @@ foreach(rule ${rules}) set(rule_cpp ${CMAKE_CURRENT_BINARY_DIR}/rules/rule_${rule}.cpp) add_custom_command(OUTPUT ${rule_cpp} - COMMAND makerls ${rule_file} ${rule_cpp} ${rule} + COMMAND ${rules_command} ${rule_file} ${rule_cpp} ${rule} DEPENDS makerls ${rule_file} ) endforeach()