From 6d3612bd5bc5875412953de861ac1ac8ee226aaf Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 30 Dec 2024 16:47:59 +0100 Subject: [PATCH] WASM build updates --- cmake/CMakeLists.txt | 31 +++++++++++++++++++++++++------ nix/build-all.py | 8 ++++++-- pyodide/meta.yaml | 6 ++++-- src/ifcwrap/CMakeLists.txt | 3 +++ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 6efc981d96..e602aaa5bf 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -196,13 +196,25 @@ foreach(option_flag IN LISTS option_flags) convert_env_var_to_bool("${option_flag}") endforeach() +set(CMAKE_FIND_ROOT_PATH_BACKUP "${CMAKE_FIND_ROOT_PATH}") + +macro(clear_wasm_sysroot) if(WASM_BUILD) # when using the nix/build-all.py build script we should not # look into the sysroot for most of the dependencies but rather # in the designated build/ folder created by the script. - set(CMAKE_FIND_ROOT_PATH_BACKUP "${CMAKE_FIND_ROOT_PATH}") set(CMAKE_FIND_ROOT_PATH "") endif() +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) +endmacro() + +macro(restore_wasm_sysroot) +if(WASM_BUILD) + # reset to use sysroot + set(CMAKE_FIND_ROOT_PATH "${CMAKE_FIND_ROOT_PATH_BACKUP}") +endif() +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endmacro() if(WITH_CGAL) add_definitions(-DIFOPSH_WITH_CGAL) @@ -223,7 +235,9 @@ endif() if(GLTF_SUPPORT OR CITYJSON_SUPPORT) UNIFY_ENVVARS_AND_CACHE(JSON_INCLUDE_DIR) + clear_wasm_sysroot() find_path(json_header_path "nlohmann/json.hpp" HINTS ${JSON_INCLUDE_DIR}) + restore_wasm_sysroot() set(JSON_INCLUDE_DIR ${json_header_path}) if(json_header_path) @@ -330,13 +344,17 @@ if(USE_MMAP) add_definitions(-DUSE_MMAP) endif() +clear_wasm_sysroot() find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) +restore_wasm_sysroot() message(STATUS "Boost include files found in ${Boost_INCLUDE_DIRS}") message(STATUS "Boost libraries found in ${Boost_LIBRARY_DIRS}") if(NOT MINIMAL_BUILD) # libxml2 is required for IFCXML (optional) and SVGFILL (mandatory) + clear_wasm_sysroot() find_package(LibXml2 REQUIRED) + restore_wasm_sysroot() endif() if(IFCXML_SUPPORT) @@ -352,6 +370,7 @@ if(BUILD_IFCGEOM) # Open CASCADE if(WITH_OPENCASCADE) if("${OCC_INCLUDE_DIR}" STREQUAL "") + clear_wasm_sysroot() find_path(OCC_INCLUDE_DIR Standard_Version.hxx PATHS /usr/include/occt @@ -359,6 +378,7 @@ if(BUILD_IFCGEOM) /usr/include/opencascade REQUIRED ) + restore_wasm_sysroot() if(OCC_INCLUDE_DIR) message(STATUS "Found Open CASCADE include files in: ${OCC_INCLUDE_DIR}") @@ -418,7 +438,9 @@ if(BUILD_IFCGEOM) message(STATUS "Looking for Open CASCADE library files in: ${OCC_LIBRARY_DIR}") endif() + clear_wasm_sysroot() find_library(libTKernel NAMES TKernel TKerneld PATHS ${OCC_LIBRARY_DIR} NO_DEFAULT_PATH) + restore_wasm_sysroot() if(libTKernel) message(STATUS "Required Open Cascade Library files found") @@ -641,11 +663,6 @@ if(HDF5_SUPPORT) set(SWIG_DEFINES ${SWIG_DEFINES} -DWITH_HDF5) endif(HDF5_SUPPORT) -if(WASM_BUILD) - # reset to use sysroot - set(CMAKE_FIND_ROOT_PATH "${CMAKE_FIND_ROOT_PATH_BACKUP}") -endif() - if(ENABLE_BUILD_OPTIMIZATIONS) if(MSVC) # NOTE: RelWithDebInfo and Release use O2 (= /Ox /Gl /Gy/ = Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy) by default, @@ -925,8 +942,10 @@ endif() if(BUILD_IFCGEOM) if(WITH_CGAL) + clear_wasm_sysroot() find_library(libGMP NAMES gmp mpir PATHS ${GMP_LIBRARY_DIR} NO_DEFAULT_PATH) find_library(libMPFR NAMES mpfr PATHS ${MPFR_LIBRARY_DIR} NO_DEFAULT_PATH) + restore_wasm_sysroot() if(NOT libGMP) message(FATAL_ERROR "Unable to find GMP library files, aborting") endif() diff --git a/nix/build-all.py b/nix/build-all.py index ef9f65da9d..9331aaded5 100644 --- a/nix/build-all.py +++ b/nix/build-all.py @@ -479,7 +479,7 @@ if platform.system() == "Darwin": ADDITIONAL_ARGS = [f"-mmacosx-version-min={TOOLSET}"] + ADDITIONAL_ARGS if "wasm" in flags: - ADDITIONAL_ARGS.extend(("-sWASM_BIGINT", "-fexceptions")) + ADDITIONAL_ARGS.extend(("-sWASM_BIGINT", "-fwasm-exceptions")) # If the linker supports GC sections, set it up to reduce binary file size # -fPIC is required for the shared libraries to work @@ -990,7 +990,11 @@ if "IfcOpenShell-Python" in targets: if platform.system() != "Darwin": if BUILD_CFG == "Release": # TODO: This symbol name depends on the Python version? - run([strip, "-s", "-K", "PyInit__ifcopenshell_wrapper", glob.glob(os.path.join(module_dir, "_ifcopenshell_wrapper*.so"))[0]], cwd=module_dir) + so = glob.glob(os.path.join(module_dir, "_ifcopenshell_wrapper*.so"))[0] + if "wasm" in flags: + run(['wasm-strip', so, '-k', "dylink.0"]) + else: + run([strip, "-s", "-K", "PyInit__ifcopenshell_wrapper", so], cwd=module_dir) return module_dir diff --git a/pyodide/meta.yaml b/pyodide/meta.yaml index f23b76a752..88de0f1e1d 100644 --- a/pyodide/meta.yaml +++ b/pyodide/meta.yaml @@ -3,12 +3,14 @@ package: version: 0.8.0 source: - path: IfcOpenShell + path: ../../IfcOpenShell build: script: | - python nix/build-all.py --without-hdf5 --without-opencollada --without-swig --without-pcre -v --wasm --py310 IfcOpenShell-Python + BUILD_CFG=Release python nix/build-all.py --without-hdf5 --without-opencollada --without-swig --without-pcre -v --wasm --py312 IfcOpenShell-Python + mv package/ifcopenshell . cp pyodide/setup.py . + mv dist/IfcOpenShell-0.8.0-py3-none-any.whl dist/ifcopenshell-python-v0.8.0-${GITHUB_SHA:0:7}-cp312-cp312-emscripten_3_1_58_wasm32.whl about: home: http://ifcopenshell.org diff --git a/src/ifcwrap/CMakeLists.txt b/src/ifcwrap/CMakeLists.txt index 863fefb67a..187f0f958d 100644 --- a/src/ifcwrap/CMakeLists.txt +++ b/src/ifcwrap/CMakeLists.txt @@ -83,13 +83,16 @@ endif() # directory in which the wrapper can be installed. FIND_PACKAGE(PythonInterp) IF((PYTHONINTERP_FOUND AND NOT "${PYTHON_EXECUTABLE}" STREQUAL "") OR PYTHON_MODULE_INSTALL_DIR) + if (NOT WASM_BUILD) # Find Python interpreter and get its version + # Not on WASM because we're cross compiling in that case EXECUTE_PROCESS( COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))" OUTPUT_VARIABLE PYTHON_EXTENSION_SUFFIX OUTPUT_STRIP_TRAILING_WHITESPACE ) SET_TARGET_PROPERTIES(${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME} PROPERTIES SUFFIX ${PYTHON_EXTENSION_SUFFIX}) + endif() if (PYTHON_MODULE_INSTALL_DIR) set(python_package_dir "${PYTHON_MODULE_INSTALL_DIR}") else()