diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 6c74da542f..349e6c1cde 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -54,6 +54,7 @@ OPTION(USE_VLD "Use Visual Leak Detector for debugging memory leaks, MSVC-only."
OPTION(USE_MMAP "Adds a command line options to parse IFC files from memory mapped files using Boost.Iostreams" OFF)
OPTION(BUILD_SHARED_LIBS "Build IfcParse and IfcGeom as shared libs (SO/DLL)." OFF)
OPTION(MSVC_PARALLEL_BUILD "Multi-threaded compilation in Microsoft Visual Studio (/MP)" OFF)
+OPTION(WASM_BUILD OFF)
if (${HAS_MAX})
OPTION(BUILD_IFCMAX "Build IfcMax, a 3ds Max plug-in, Windows-only." OFF)
endif()
@@ -149,6 +150,14 @@ UNIFY_ENVVARS_AND_CACHE(MPFR_INCLUDE_DIR)
UNIFY_ENVVARS_AND_CACHE(MPFR_LIBRARY_DIR)
endif()
+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()
+
if (NOT MINIMAL_BUILD AND GLTF_SUPPORT AND BUILD_CONVERT)
UNIFY_ENVVARS_AND_CACHE(JSON_INCLUDE_DIR)
FIND_FILE(json_hpp "json.hpp" ${JSON_INCLUDE_DIR}/nlohmann)
@@ -199,7 +208,14 @@ ELSE()
ENDIF()
ENDIF()
-set(BOOST_COMPONENTS system program_options regex thread date_time)
+if (WASM_BUILD)
+ set(BOOST_COMPONENTS)
+else()
+ # @todo review this, shouldn't this be all possible header-only now?
+ # ... or rewritten using C++17 features?
+ set(BOOST_COMPONENTS system program_options regex thread date_time)
+endif()
+
if(USE_MMAP)
if(MSVC)
# filesystem is necessary for the utf-16 wpath
@@ -210,6 +226,10 @@ if(USE_MMAP)
add_definitions(-DUSE_MMAP)
endif()
+FIND_PACKAGE(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
+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)
find_package(LibXml2 REQUIRED)
@@ -220,11 +240,6 @@ if (NOT MINIMAL_BUILD AND IFCXML_SUPPORT)
set(SWIG_DEFINES ${SWIG_DEFINES} -DWITH_IFCXML)
endif()
-FIND_PACKAGE(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
-MESSAGE(STATUS "Boost include files found in ${Boost_INCLUDE_DIRS}")
-MESSAGE(STATUS "Boost libraries found in ${Boost_LIBRARY_DIRS}")
-
-
# Usage:
# set(SOME_LIRARIES foo bar)
# add_debug_variants(SOME_LIRARIES "${SOME_LIRARIES}" d)
@@ -343,10 +358,21 @@ if("${libTKernelExt}" STREQUAL ".a")
set(OCCT_STATIC ON)
endif()
+if(WASM_BUILD)
+ set(CMAKE_FIND_ROOT_PATH "${CMAKE_FIND_ROOT_PATH_BACKUP}")
+endif()
+
if(OCCT_STATIC)
find_package(Threads)
- # OPENCASCADE_LIBRARIES repeated three times below in order to fix cyclic dependencies - use --start-group ... --end-group instead?
- set(OPENCASCADE_LIBRARIES ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+
+ if(WASM_BUILD)
+ set(OPENCASCADE_LIBRARIES ${OPENCASCADE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+ else()
+ # OPENCASCADE_LIBRARIES repeated N times below in order to fix cyclic dependencies - use --start-group ... --end-group instead?
+ # tfk: --start-group ... --end-group didn't work on the apple linker when last tested
+ set(OPENCASCADE_LIBRARIES ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+ endif()
+
if (NOT APPLE AND NOT WIN32)
set(OPENCASCADE_LIBRARIES ${OPENCASCADE_LIBRARIES} "rt")
endif()
@@ -620,7 +646,12 @@ function(files_for_ifc_version IFC_VERSION RESULT_NAME)
endfunction()
if(NOT SCHEMA_VERSIONS)
- set(SCHEMA_VERSIONS "2x3" "4" "4x1" "4x2" "4x3_rc1" "4x3_rc2" "4x3_rc3" "4x3_rc4" "4x3" "4x3_tc1" "4x3_add1")
+ if(WASM_BUILD)
+ # super arbitrarily try to keep size down at least a little bit
+ set(SCHEMA_VERSIONS "2x3" "4")
+ else()
+ set(SCHEMA_VERSIONS "2x3" "4" "4x1" "4x2" "4x3_rc1" "4x3_rc2" "4x3_rc3" "4x3_rc4" "4x3" "4x3_tc1" "4x3_add1")
+ endif()
endif()
foreach(s ${SCHEMA_VERSIONS})
@@ -697,7 +728,11 @@ if (BUILD_IFCGEOM)
foreach(s ${SCHEMA_VERSIONS})
set(IFCGEOM_SCHEMA_LIBRARIES ${IFCGEOM_SCHEMA_LIBRARIES} IfcGeom_ifc${s})
endforeach()
- set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES})
+ if (WASM_BUILD)
+ set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES})
+ else()
+ set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES} IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES})
+ endif()
endif()
if (BUILD_CONVERT OR BUILD_IFCPYTHON)
foreach(s ${SCHEMA_VERSIONS})
@@ -741,7 +776,11 @@ set(IFCPARSE_FILES ${IFCPARSE_CPP_FILES} ${IFCPARSE_H_FILES})
add_library(IfcParse ${IFCPARSE_FILES})
set_target_properties(IfcParse PROPERTIES COMPILE_FLAGS -DIFC_PARSE_EXPORTS VERSION "0.6.0" SOVERSION "0.6")
-TARGET_LINK_LIBRARIES(IfcParse ${Boost_LIBRARIES} ${BCRYPT_LIBRARIES} ${LIBXML2_LIBRARIES})
+if (WASM_BUILD)
+ TARGET_LINK_LIBRARIES(IfcParse ${BCRYPT_LIBRARIES} ${LIBXML2_LIBRARIES})
+else()
+ TARGET_LINK_LIBRARIES(IfcParse ${Boost_LIBRARIES} ${BCRYPT_LIBRARIES} ${LIBXML2_LIBRARIES})
+endif()
if (BUILD_IFCGEOM)
@@ -753,7 +792,9 @@ set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES})
foreach(s ${SCHEMA_VERSIONS})
add_library(IfcGeom_ifc${s} STATIC ${IFCGEOM_FILES})
set_target_properties(IfcGeom_ifc${s} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${s}")
- TARGET_LINK_LIBRARIES(IfcGeom_ifc${s} IfcParse ${OPENCASCADE_LIBRARIES})
+ if (NOT WASM_BUILD)
+ TARGET_LINK_LIBRARIES(IfcGeom_ifc${s} IfcParse ${OPENCASCADE_LIBRARIES})
+ endif()
endforeach()
# IfcGeom (schema agnostic)
@@ -768,7 +809,11 @@ if (UNIX)
find_package(Threads)
endif()
-TARGET_LINK_LIBRARIES(IfcGeom IfcParse ${IFCGEOM_SCHEMA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+if (WASM_BUILD)
+ TARGET_LINK_LIBRARIES(IfcGeom ${IFCGEOM_SCHEMA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+else()
+ TARGET_LINK_LIBRARIES(IfcGeom IfcParse ${IFCGEOM_SCHEMA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+endif()
endif(BUILD_IFCGEOM)
@@ -785,7 +830,12 @@ set(SERIALIZERS_S_FILES ${SERIALIZERS_S_H_FILES} ${SERIALIZERS_S_CPP_FILES})
foreach(s ${SCHEMA_VERSIONS})
add_library(Serializers_ifc${s} STATIC ${SERIALIZERS_S_FILES})
set_target_properties(Serializers_ifc${s} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${s} ${CONVERT_PRECISION}")
- TARGET_LINK_LIBRARIES(Serializers_ifc${s} IfcGeom ${OPENCASCADE_LIBRARIES} ${HDF5_LIBRARIES})
+
+ if (WASM_BUILD)
+ TARGET_LINK_LIBRARIES(Serializers_ifc${s} ${HDF5_LIBRARIES})
+ else()
+ TARGET_LINK_LIBRARIES(Serializers_ifc${s} IfcGeom ${OPENCASCADE_LIBRARIES} ${HDF5_LIBRARIES})
+ endif()
endforeach()
add_library(Serializers ${SERIALIZERS_FILES})
diff --git a/nix/build-all.py b/nix/build-all.py
index b052db4ae5..a856f61ccb 100644
--- a/nix/build-all.py
+++ b/nix/build-all.py
@@ -26,7 +26,7 @@
# * cmake * git * bzip2 * tar * c(++) compilers * autoconf #
# #
# if building with USE_OCCT additionally: #
-# * freetype * glx.h #
+# * glx.h #
# #
# if building with OCCT 7.4.0 additionally: #
# * libfontconfig1-dev #
@@ -39,14 +39,14 @@
# #
# on debian 7.8 these can be obtained with: #
# $ apt-get install git gcc g++ autoconf bison bzip2 cmake #
-# libfreetype6-dev mesa-common-dev libffi-dev libfontconfig1-dev #
+# mesa-common-dev libffi-dev libfontconfig1-dev #
# #
# on ubuntu 14.04: #
# $ apt-get install git gcc g++ autoconf bison make cmake #
-# libfreetype6-dev mesa-common-dev libffi-dev libfontconfig1-dev #
+# mesa-common-dev libffi-dev libfontconfig1-dev #
# #
# on OS X El Capitan with homebrew: #
-# $ brew install git bison autoconf automake freetype libffi cmake #
+# $ brew install git bison autoconf automake libffi cmake #
# #
###############################################################################
import logging
@@ -76,7 +76,7 @@ PYTHON_VERSIONS = ["3.6.14", "3.7.13", "3.8.13", "3.9.11", "3.10.3", "3.11.0"]
JSON_VERSION = "v3.6.1"
OCE_VERSION = "0.18.3"
OCCT_VERSION = "7.5.3"
-BOOST_VERSION = "1.71.0"
+BOOST_VERSION = "1.80.0"
PCRE_VERSION = "8.41"
LIBXML2_VERSION = "2.9.11"
SWIG_VERSION = "4.0.2"
@@ -103,6 +103,9 @@ curl = "curl"
wget = "wget"
strip = "strip"
+explicit_targets = [s for s in sys.argv[1:] if not s.startswith("-")]
+flags = set(s.lstrip('-') for s in sys.argv[1:] if s.startswith("-"))
+
# Helper function for coloured printing
NO_COLOR = "\033[0m" # [http://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux]
@@ -135,9 +138,11 @@ if platform.system() == "Darwin":
IFCOS_NUM_BUILD_PROCS = os.getenv("IFCOS_NUM_BUILD_PROCS", multiprocessing.cpu_count() + 1)
-CMAKE_DIR = os.path.realpath(os.path.join("..", "cmake"))
+CMAKE_DIR = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "cmake"))
-path = ["..", "build", platform.system(), platform.machine()]
+build_dir = os.environ.get("BUILD_DIR", os.path.join(os.path.dirname(__file__), "..", "build"))
+
+path = [build_dir, platform.system(), "wasm" if "wasm" in flags else platform.machine()]
if TOOLSET:
path.append(TOOLSET)
DEFAULT_DEPS_DIR = os.path.realpath(os.path.join(*path))
@@ -186,11 +191,12 @@ dependency_tree = {
'boost': (),
'libxml2': (),
'python': (),
- 'occ': (),
+ 'occ': ('freetype',),
'pcre': (),
'json': (),
'hdf5': (),
- 'cgal': ()
+ 'cgal': (),
+ 'freetype': (),
}
def v(dep):
@@ -199,10 +205,12 @@ def v(dep):
for x in v(d):
yield x
-tgts = [s for s in sys.argv[1:] if not s.startswith("-")]
-flags = set(s for s in sys.argv[1:] if s.startswith("-"))
+if "v" in flags:
+ logger.setLevel(logging.DEBUG)
+else:
+ logger.setLevel(logging.INFO)
-BUILD_STATIC = not "-shared" in flags
+BUILD_STATIC = "shared" not in flags
ENABLE_FLAG = "--enable-static" if BUILD_STATIC else "--enable-shared"
DISABLE_FLAG = "--disable-shared" if BUILD_STATIC else "--disable-static"
LINK_TYPE = "static" if BUILD_STATIC else "shared"
@@ -210,10 +218,15 @@ LINK_TYPE_UCFIRST = LINK_TYPE[0].upper() + LINK_TYPE[1:]
LIBRARY_EXT = "a" if BUILD_STATIC else "so"
PIC = "-fPIC" if BUILD_STATIC else ""
-if len(tgts):
- targets = set(sum((list(v(target)) for target in tgts), []))
+if any(f.startswith("py-") for f in flags):
+ PYTHON_VERSIONS = [pyv for pyv in PYTHON_VERSIONS if "py-%s" % "".join(pyv.split('.')[0:2]) in flags]
+
+if len(explicit_targets):
+ targets = set(sum((list(v(target)) for target in explicit_targets), []))
else:
targets = set(dependency_tree.keys())
+
+targets = set(t for t in targets if 'without-%s' % t.lower() not in flags)
print("Building:", *sorted(targets, key=lambda t: len(list(v(t)))))
@@ -237,7 +250,7 @@ if not os.path.exists(LOG_FILE):
open(LOG_FILE, "w").close()
logger.info(f"using command log file '{LOG_FILE}'")
-def run(cmds, cwd=None):
+def run(cmds, cwd=None, can_fail=False):
"""
Wraps `subprocess.Popen.communicate()` and logs the command being executed,
@@ -254,7 +267,7 @@ def run(cmds, cwd=None):
log_file_handle.close()
logger.debug(f"command returned {proc.returncode}")
- if proc.returncode != 0:
+ if proc.returncode != 0 and not can_fail:
print("-" * 70)
print(stderr)
print("-" * 70)
@@ -284,7 +297,12 @@ def run_autoconf(arg1, configure_args, cwd):
run([bash, "./autogen.sh"], cwd=os.path.realpath(os.path.join(cwd, ".."))) # only run autogen.sh in the directory it is located and use cwd to achieve that in order to not mess up things
# Using `sh` over `bash` fixes issues with building swig
prefix = os.path.realpath(f"{DEPS_DIR}/install/{arg1}")
- run(["/bin/sh", "../configure"] + configure_args + [f"--prefix={prefix}"], cwd=cwd)
+
+ wasm = []
+ if "wasm" in flags:
+ wasm.append("emconfigure")
+
+ run([*wasm, "/bin/sh", "../configure"] + configure_args + [f"--prefix={prefix}"], cwd=cwd)
def run_cmake(arg1, cmake_args, cmake_dir=None, cwd=None):
@@ -292,7 +310,12 @@ def run_cmake(arg1, cmake_args, cmake_dir=None, cwd=None):
P = ".."
else:
P = cmake_dir
- run(["cmake", P] + cmake_args + [f"-DCMAKE_BUILD_TYPE={BUILD_CFG}"], cwd=cwd)
+
+ wasm = []
+ if "wasm" in flags:
+ wasm.append("emcmake")
+
+ run([*wasm, "cmake", P, *cmake_args, f"-DCMAKE_BUILD_TYPE={BUILD_CFG}"], cwd=cwd)
def git_clone_or_pull_repository(clone_url, target_dir, revision=None):
@@ -374,12 +397,15 @@ def build_dependency(name, mode, build_tool_args, download_url, download_name, d
urlretrieve(url, os.path.join(extract_dir, path))
if patch is not None:
- patch_abs = os.path.abspath(os.path.join(os.path.dirname(__file__), patch))
- if os.path.exists(patch_abs):
- try: run(["patch", "-p1", "--batch", "--forward", "-i", patch_abs], cwd=extract_dir)
- except Exception as e:
- # Assert that the patch has already been applied
- run(["patch", "-p1", "--batch", "--reverse", "--dry-run", "-i", patch_abs], cwd=extract_dir)
+ if isinstance(patch, str):
+ patch = [patch]
+ for p in patch:
+ patch_abs = os.path.abspath(os.path.join(os.path.dirname(__file__), p))
+ if os.path.exists(patch_abs):
+ try: run(["patch", "-p1", "--batch", "--forward", "-i", patch_abs], cwd=extract_dir)
+ except Exception as e:
+ # Assert that the patch has already been applied
+ run(["patch", "-p1", "--batch", "--reverse", "--dry-run", "-i", patch_abs], cwd=extract_dir)
if mode == "ctest":
run(["ctest", "-S", "HDF5config.cmake,BUILD_GENERATOR=Unix", "-C", BUILD_CFG, "-V", "-O", "hdf5.log"], cwd=extract_dir)
@@ -410,7 +436,7 @@ def build_dependency(name, mode, build_tool_args, download_url, download_name, d
logger.info(f"\rConfiguring {name}...")
run([bash, "./bootstrap.sh"], cwd=extract_dir)
logger.info(f"\rBuilding {name}... ")
- run(["./b2", f"-j{IFCOS_NUM_BUILD_PROCS}"] + build_tool_args, cwd=extract_dir)
+ run(["./b2", f"-j{IFCOS_NUM_BUILD_PROCS}"] + build_tool_args, cwd=extract_dir, can_fail="wasm" in flags)
logger.info(f"\rInstalling {name}... ")
shutil.copytree(os.path.join(extract_dir, "boost"), os.path.join(DEPS_DIR, "install", f"boost-{BOOST_VERSION}", "boost"))
logger.info(f"\rInstalled {name} \n")
@@ -421,11 +447,13 @@ cecho("Collecting dependencies:", GREEN)
# TODO: This is untested
ADDITIONAL_ARGS = []
-BOOST_ADDRESS_MODEL = []
if platform.system() == "Darwin":
ADDITIONAL_ARGS = [f"-mmacosx-version-min={TOOLSET}"] + ADDITIONAL_ARGS
+if "wasm" in flags:
+ ADDITIONAL_ARGS.extend(("-sWASM_BIGINT", "-fexceptions"))
+
# If the linker supports GC sections, set it up to reduce binary file size
# -fPIC is required for the shared libraries to work
@@ -434,7 +462,7 @@ CFLAGS = os.environ.get("CFLAGS", "")
LDFLAGS = os.environ.get("LDFLAGS", "")
ADDITIONAL_ARGS_STR = " ".join(ADDITIONAL_ARGS)
-if sp.call([bash, "-c", "ld --gc-sections 2>&1 | grep -- --gc-sections &> /dev/null"]) != 0:
+if "wasm" not in flags and sp.call([bash, "-c", "ld --gc-sections 2>&1 | grep -- --gc-sections &> /dev/null"]) != 0:
CXXFLAGS_MINIMAL = f"{CXXFLAGS} {PIC} {ADDITIONAL_ARGS_STR}"
CFLAGS_MINIMAL = f"{CFLAGS} {PIC} {ADDITIONAL_ARGS_STR}"
if BUILD_STATIC:
@@ -504,8 +532,27 @@ if "swig" in targets:
download_tool=download_tool_git,
revision=f"rel-{SWIG_VERSION}"
)
+
+if "freetype" in targets:
+ build_dependency(
+ name=f"freetype",
+ mode="cmake",
+ build_tool_args=[
+ f"-DCMAKE_INSTALL_PREFIX={DEPS_DIR}/install/freetype"
+ ],
+ download_url = "https://github.com/freetype/freetype",
+ download_name = "freetype2",
+ download_tool=download_tool_git,
+ )
if USE_OCCT and "occ" in targets:
+ patches = []
+ if OCCT_VERSION < "7.4":
+ patches.append("./patches/occt/enable-exception-handling.patch")
+
+ if "wasm" in flags:
+ patches.append("./patches/occt/no_em_js.patch")
+
build_dependency(
name=f"occt-{OCCT_VERSION}",
mode="cmake",
@@ -513,12 +560,13 @@ if USE_OCCT and "occ" in targets:
f"-DINSTALL_DIR={DEPS_DIR}/install/occt-{OCCT_VERSION}",
f"-DBUILD_LIBRARY_TYPE={LINK_TYPE_UCFIRST}",
"-DBUILD_MODULE_Draw=0",
- "-DBUILD_RELEASE_DISABLE_EXCEPTIONS=Off"
+ "-DBUILD_RELEASE_DISABLE_EXCEPTIONS=Off",
+ f"-D3RDPARTY_FREETYPE_DIR={DEPS_DIR}/install/freetype"
],
download_url = "https://github.com/Open-Cascade-SAS/OCCT",
download_name = "occt",
download_tool=download_tool_git,
- patch=None if OCCT_VERSION >= "7.4" else "./patches/occt/enable-exception-handling.patch",
+ patch=patches,
revision="V" + OCCT_VERSION.replace('.', '_')
)
elif "occ" in targets:
@@ -569,11 +617,11 @@ if "OpenCOLLADA" in targets:
download_url="https://github.com/KhronosGroup/OpenCOLLADA.git",
download_name="OpenCOLLADA",
download_tool=download_tool_git,
- patch="./patches/opencollada/pr622_and_disable_subdirs.patch",
+ patch=("./patches/opencollada/pr622_and_disable_subdirs.patch", "./patches/opencollada/remove_tr1.patch"),
revision=OPENCOLLADA_VERSION
)
-if "python" in targets and not USE_CURRENT_PYTHON_VERSION:
+if "python" in targets and not USE_CURRENT_PYTHON_VERSION and "wasm" not in flags:
# Python should not be built with -fvisibility=hidden, from experience that introduces segfaults
OLD_CXX_FLAGS = os.environ["CXXFLAGS"]
OLD_C_FLAGS = os.environ["CFLAGS"]
@@ -612,6 +660,9 @@ if "python" in targets and not USE_CURRENT_PYTHON_VERSION:
if "boost" in targets:
str_concat = lambda prefix: lambda postfix: "" if postfix.strip() == "" else "=".join((prefix, postfix.strip()))
+ toolset = []
+ if "wasm" in flags:
+ toolset.append("toolset=emscripten")
build_dependency(
f"boost-{BOOST_VERSION}",
mode="bjam",
@@ -623,21 +674,30 @@ if "boost" in targets:
"--with-thread",
"--with-date_time",
"--with-iostreams",
- f"link={LINK_TYPE}"
- ] + \
- BOOST_ADDRESS_MODEL + \
- list(map(str_concat("cxxflags"), CXXFLAGS.strip().split(' '))) + \
- list(map(str_concat("linkflags"), LDFLAGS.strip().split(' '))) + \
- ["stage", "-s", "NO_BZIP2=1"],
+ f"link={LINK_TYPE}",
+ *toolset,
+ *map(str_concat("cxxflags"), CXXFLAGS.strip().split(' ')),
+ *map(str_concat("linkflags"), LDFLAGS.strip().split(' ')),
+ "stage", "-s", "NO_BZIP2=1"],
download_url=BOOST_LOCATION,
+ patch="./patches/boost/boostorg_regex_62.patch",
download_name=f"boost_{BOOST_VERSION_UNDERSCORE}.tar.bz2"
)
+ if "wasm" in flags:
+ # only supported on nix for now
+ run(("find", ".", "-name", "*.bc", "-exec", "bash", "-c", "emar q ${1%.bc}.a $1", "bash", "{}", ";"), cwd=f"{DEPS_DIR}/install/boost-{BOOST_VERSION}/lib")
if "cgal" in targets:
+ gmp_args = []
+ mpfr_args = []
+ if "wasm" in flags:
+ gmp_args.extend(("--disable-assembly", "--host", "none", "--enable-cxx"))
+ mpfr_args.extend(("--host", "none"))
+
build_dependency(
name=f"gmp-{GMP_VERSION}",
mode="autoconf",
- build_tool_args=[ENABLE_FLAG, DISABLE_FLAG, "--with-pic"],
+ build_tool_args=[ENABLE_FLAG, DISABLE_FLAG, "--with-pic", *gmp_args],
download_url="https://ftp.gnu.org/gnu/gmp/",
download_name=f"gmp-{GMP_VERSION}.tar.bz2"
)
@@ -645,7 +705,7 @@ if "cgal" in targets:
build_dependency(
name=f"mpfr-{MPFR_VERSION}",
mode="autoconf",
- build_tool_args=[ENABLE_FLAG, DISABLE_FLAG, f"--with-gmp={DEPS_DIR}/install/gmp-{GMP_VERSION}"],
+ build_tool_args=[ENABLE_FLAG, DISABLE_FLAG, *mpfr_args, f"--with-gmp={DEPS_DIR}/install/gmp-{GMP_VERSION}"],
download_url=f"http://www.mpfr.org/mpfr-{MPFR_VERSION}/",
download_name=f"mpfr-{MPFR_VERSION}.tar.bz2"
)
@@ -679,18 +739,8 @@ os.makedirs(IFCOS_DIR, exist_ok=True)
executables_dir = os.path.join(IFCOS_DIR, "executables")
os.makedirs(executables_dir, exist_ok=True)
-logger.info("\rConfiguring executables...")
-
OFF_ON = ["OFF", "ON"]
-exec_args = [
- "-DBUILD_IFCGEOM=" +OFF_ON["IfcGeom" in targets],
- "-DBUILD_GEOMSERVER=" +OFF_ON["IfcGeomServer" in targets],
- "-DBUILD_CONVERT=" +OFF_ON["IfcConvert" in targets],
- "-DBUILD_IFCPYTHON=" "OFF",
- "-DCMAKE_INSTALL_PREFIX=" f"{DEPS_DIR}/install/ifcopenshell",
-]
-
cmake_args = [
"-DUSE_MMAP=" "OFF",
"-DBUILD_EXAMPLES=" "OFF",
@@ -702,6 +752,11 @@ cmake_args = [
"-DADD_COMMIT_SHA=" +("On" if ADD_COMMIT_SHA else "Off")
]
+if "wasm" in flags:
+ # Boost is built by the build script so should not be found
+ # inside of the sysroot set by the emscriptem toolchain
+ cmake_args.append("-DWASM_BUILD=On")
+
if "cgal" in targets:
cmake_args.extend([
"-DCGAL_INCLUDE_DIR=" f"{DEPS_DIR}/install/cgal-{CGAL_VERSION}/include",
@@ -753,20 +808,36 @@ if "hdf5" in targets:
"-DHDF5_INCLUDE_DIR=" f"{DEPS_DIR}/install/hdf5-{HDF5_VERSION}/include",
"-DHDF5_LIBRARY_DIR=" f"{DEPS_DIR}/install/hdf5-{HDF5_VERSION}/lib"
])
+else:
+ cmake_args.append("-DHDF5_SUPPORT=Off")
-run_cmake("", exec_args + cmake_args, cmake_dir=CMAKE_DIR, cwd=executables_dir)
+if not explicit_targets or {"IfcGeom", "IfcConvert", "IfcGeomServer"} & set(explicit_targets):
+ logger.info("\rConfiguring executables...")
-logger.info("\rBuilding executables... ")
+ exec_args = [
+ "-DBUILD_IFCGEOM=" +OFF_ON["IfcGeom" in targets],
+ "-DBUILD_GEOMSERVER=" +OFF_ON["IfcGeomServer" in targets],
+ "-DBUILD_CONVERT=" +OFF_ON["IfcConvert" in targets],
+ "-DBUILD_IFCPYTHON=" "OFF",
+ "-DCMAKE_INSTALL_PREFIX=" f"{DEPS_DIR}/install/ifcopenshell",
+ ]
+
+ run_cmake("", exec_args + cmake_args, cmake_dir=CMAKE_DIR, cwd=executables_dir)
-run([make, f"-j{IFCOS_NUM_BUILD_PROCS}"], cwd=executables_dir)
-run([make, "install/strip" if BUILD_CFG == "Release" else "install"], cwd=executables_dir)
+ logger.info("\rBuilding executables... ")
+
+ run([make, f"-j{IFCOS_NUM_BUILD_PROCS}"], cwd=executables_dir)
+ run([make, "install/strip" if BUILD_CFG == "Release" else "install"], cwd=executables_dir)
if "IfcOpenShell-Python" in targets:
# On OSX the actual Python library is not linked against.
ADDITIONAL_ARGS = ""
if platform.system() == "Darwin":
ADDITIONAL_ARGS = "-Wl,-flat_namespace,-undefined,suppress"
-
+
+ if "wasm" in flags:
+ ADDITIONAL_ARGS = f"-Wl,-undefined,suppress -sSIDE_MODULE=2 -sEXPORTED_FUNCTIONS=_PyInit__ifcopenshell_wrapper"
+
os.environ["CXXFLAGS"] = f"{CXXFLAGS_MINIMAL} {ADDITIONAL_ARGS}"
os.environ["CFLAGS"] = f"{CFLAGS_MINIMAL} {ADDITIONAL_ARGS}"
os.environ["LDFLAGS"] = f"{LDFLAGS} {ADDITIONAL_ARGS}"
@@ -783,36 +854,57 @@ if "IfcOpenShell-Python" in targets:
os.environ["PYTHON_LIBRARY_BASENAME"] = os.path.basename(python_library)
+ swig_when_built = []
+ if "swig" in targets:
+ swig_when_built.append(f"-DSWIG_EXECUTABLE={DEPS_DIR}/install/swig/bin/swig")
+
run_cmake("",
cmake_args + [
"-DPYTHON_LIBRARY=" +python_library,
- "-DPYTHON_EXECUTABLE=" +python_executable,
+ *([f"-DPYTHON_EXECUTABLE={python_executable}"] if python_executable else []),
+ # *([f"-DPYTHON_MODULE_INSTALL_DIR={os.environ['PYTHONPATH']}/ifcopenshell"] if "wasm" in flags else []),
+ *(["-DPYTHON_MODULE_INSTALL_DIR="+os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "package"))] if "wasm" in flags else []),
"-DPYTHON_INCLUDE_DIR=" +python_include,
- "-DSWIG_EXECUTABLE=" f"{DEPS_DIR}/install/swig/bin/swig",
"-DCMAKE_INSTALL_PREFIX=" f"{DEPS_DIR}/install/ifcopenshell/tmp",
- "-DUSERSPACE_PYTHON_PREFIX=" +["Off", "On"][os.environ.get("PYTHON_USER_SITE", "").lower() in {"1", "on", "true"}]
- ], cmake_dir=CMAKE_DIR, cwd=python_dir)
+ "-DUSERSPACE_PYTHON_PREFIX=" +["Off", "On"][os.environ.get("PYTHON_USER_SITE", "").lower() in {"1", "on", "true"}],
+ *swig_when_built],
+ cmake_dir=CMAKE_DIR, cwd=python_dir)
logger.info(f"\rBuilding python {python_version} wrapper... ")
run([make, f"-j{IFCOS_NUM_BUILD_PROCS}", "_ifcopenshell_wrapper"], cwd=python_dir)
run([make, "install/local"], cwd=os.path.join(python_dir, "ifcwrap"))
- module_dir = os.path.dirname(run([python_executable, "-c", "import inspect, ifcopenshell; print(inspect.getfile(ifcopenshell))"]))
+ if python_executable:
+ module_dir = os.path.dirname(run([python_executable, "-c", "import inspect, ifcopenshell; print(inspect.getfile(ifcopenshell))"]))
- if platform.system() != "Darwin":
- # TODO: This symbol name depends on the Python version?
- run([strip, "-s", "-K", "PyInit__ifcopenshell_wrapper", "_ifcopenshell_wrapper.so"], cwd=module_dir)
- return module_dir
+ if platform.system() != "Darwin":
+ # TODO: This symbol name depends on the Python version?
+ run([strip, "-s", "-K", "PyInit__ifcopenshell_wrapper", "_ifcopenshell_wrapper.so"], cwd=module_dir)
+ return module_dir
- if USE_CURRENT_PYTHON_VERSION:
- python_info = sysconfig.get_paths()
- python_lib = os.path.join(
- sysconfig.get_config_var('LIBDIR'),
- sysconfig.get_config_var('multiarchsubdir').replace("/", ""),
- sysconfig.get_config_var("INSTSONAME")
+ if "wasm" in flags:
+ compile_python_wrapper(
+ f"{os.environ['PYMAJOR']}.{os.environ['PYMINOR']}.{os.environ['PYMICRO']}",
+ f"{os.environ['TARGETINSTALLDIR']}/lib/libpython{os.environ['PYMAJOR']}.{os.environ['PYMINOR']}.a",
+ os.environ['PYTHONINCLUDE'],
+ None
)
+
+ elif USE_CURRENT_PYTHON_VERSION:
+ python_info = sysconfig.get_paths()
+
+ py_path_components = [
+ sysconfig.get_config_var('LIBDIR'),
+ sysconfig.get_config_var("INSTSONAME")
+ ]
+
+ if sysconfig.get_config_var('multiarchsubdir'):
+ py_path_components.insert(1, sysconfig.get_config_var('multiarchsubdir').replace("/", ""))
+
+ python_lib = os.path.join(*py_path_components)
+
compile_python_wrapper(platform.python_version(), python_lib, python_info["include"], sys.executable)
else:
for python_version in PYTHON_VERSIONS:
diff --git a/nix/patches/boost/boostorg_regex_62.patch b/nix/patches/boost/boostorg_regex_62.patch
new file mode 100644
index 0000000000..963a4ac73c
--- /dev/null
+++ b/nix/patches/boost/boostorg_regex_62.patch
@@ -0,0 +1,20 @@
+--- a/tools/build/src/tools/emscripten.jam
++++ b/tools/build/src/tools/emscripten.jam
+@@ -6,6 +6,7 @@
+ import feature ;
+ import os ;
+ import toolset ;
++import generators ;
+ import common ;
+ import gcc ;
+ import type ;
+@@ -52,6 +53,8 @@
+ off on
+ off on
+ ;
++generators.override builtin.lib-generator : emscripten.prebuilt ;
++generators.override emscripten.searched-lib-generator : searched-lib-generator ;
+
+ type.set-generated-target-suffix EXE : emscripten : "js" ;
+ type.set-generated-target-suffix OBJ : emscripten : "bc" ;
+
\ No newline at end of file
diff --git a/nix/patches/occt/no_em_js.patch b/nix/patches/occt/no_em_js.patch
new file mode 100644
index 0000000000..2090686f9f
--- /dev/null
+++ b/nix/patches/occt/no_em_js.patch
@@ -0,0 +1,99 @@
+diff --git a/src/Message/Message_PrinterSystemLog.cxx b/src/Message/Message_PrinterSystemLog.cxx
+index 0c82c2167..a2e9e6d68 100644
+--- a/src/Message/Message_PrinterSystemLog.cxx
++++ b/src/Message/Message_PrinterSystemLog.cxx
+@@ -55,27 +55,6 @@
+ return ANDROID_LOG_DEBUG;
+ }
+ #elif defined(__EMSCRIPTEN__)
+- #include
+-
+- //! Print message to console.debug().
+- EM_JS(void, occJSConsoleDebug, (const char* theStr), {
+- console.debug(UTF8ToString(theStr));
+- });
+-
+- //! Print message to console.info().
+- EM_JS(void, occJSConsoleInfo, (const char* theStr), {
+- console.info(UTF8ToString(theStr));
+- });
+-
+- //! Print message to console.warn().
+- EM_JS(void, occJSConsoleWarn, (const char* theStr), {
+- console.warn(UTF8ToString(theStr));
+- });
+-
+- //! Print message to console.error().
+- EM_JS(void, occJSConsoleError, (const char* theStr), {
+- console.error(UTF8ToString(theStr));
+- });
+ #else
+ #include
+
+@@ -169,16 +148,6 @@ void Message_PrinterSystemLog::send (const TCollection_AsciiString& theString,
+ #elif defined(__ANDROID__)
+ __android_log_write (getAndroidLogPriority (theGravity), myEventSourceName.ToCString(), theString.ToCString());
+ #elif defined(__EMSCRIPTEN__)
+- // don't use bogus emscripten_log() corrupting UNICODE strings
+- switch (theGravity)
+- {
+- case Message_Trace: occJSConsoleDebug(theString.ToCString()); return;
+- case Message_Info: occJSConsoleInfo (theString.ToCString()); return;
+- case Message_Warning: occJSConsoleWarn (theString.ToCString()); return;
+- case Message_Alarm: occJSConsoleError(theString.ToCString()); return;
+- case Message_Fail: occJSConsoleError(theString.ToCString()); return;
+- }
+- occJSConsoleWarn (theString.ToCString());
+ #else
+ syslog (getSysLogPriority (theGravity), "%s", theString.ToCString());
+ #endif
+diff --git a/src/OSD/OSD_MemInfo.cxx b/src/OSD/OSD_MemInfo.cxx
+index 08a939beb..7c1fc79b3 100644
+--- a/src/OSD/OSD_MemInfo.cxx
++++ b/src/OSD/OSD_MemInfo.cxx
+@@ -37,15 +37,6 @@
+
+ #include
+
+-#if defined(__EMSCRIPTEN__)
+- #include
+-
+- //! Return WebAssembly heap size in bytes.
+- EM_JS(size_t, OSD_MemInfo_getModuleHeapLength, (), {
+- return Module.HEAP8.length;
+- });
+-#endif
+-
+ // =======================================================================
+ // function : OSD_MemInfo
+ // purpose :
+@@ -156,29 +147,6 @@ void OSD_MemInfo::Update()
+ }
+
+ #elif defined(__EMSCRIPTEN__)
+- if (IsActive (MemHeapUsage)
+- || IsActive (MemWorkingSet)
+- || IsActive (MemWorkingSetPeak))
+- {
+- // /proc/%d/status is not emulated - get more info from mallinfo()
+- const struct mallinfo aMI = mallinfo();
+- if (IsActive (MemHeapUsage))
+- {
+- myCounters[MemHeapUsage] = aMI.uordblks;
+- }
+- if (IsActive (MemWorkingSet))
+- {
+- myCounters[MemWorkingSet] = aMI.uordblks;
+- }
+- if (IsActive (MemWorkingSetPeak))
+- {
+- myCounters[MemWorkingSetPeak] = aMI.usmblks;
+- }
+- }
+- if (IsActive (MemVirtual))
+- {
+- myCounters[MemVirtual] = OSD_MemInfo_getModuleHeapLength();
+- }
+ #elif (defined(__linux__) || defined(__linux))
+ if (IsActive (MemHeapUsage))
+ {
diff --git a/nix/patches/opencollada/remove_tr1.patch b/nix/patches/opencollada/remove_tr1.patch
new file mode 100644
index 0000000000..f586279d49
--- /dev/null
+++ b/nix/patches/opencollada/remove_tr1.patch
@@ -0,0 +1,81 @@
+diff --git a/COLLADABaseUtils/include/COLLADABUhash_map.h b/COLLADABaseUtils/include/COLLADABUhash_map.h
+index 8ab0fb9b..12503bfb 100644
+--- a/COLLADABaseUtils/include/COLLADABUhash_map.h
++++ b/COLLADABaseUtils/include/COLLADABUhash_map.h
+@@ -32,9 +32,9 @@
+ #include
+ #include
+
+- #define COLLADABU_HASH_MAP std::tr1::unordered_map
+- #define COLLADABU_HASH_MULTIMAP std::tr1::unordered_multimap
+- #define COLLADABU_HASH_SET std::tr1::unordered_set
++ #define COLLADABU_HASH_MAP std::unordered_map
++ #define COLLADABU_HASH_MULTIMAP std::unordered_multimap
++ #define COLLADABU_HASH_SET std::unordered_set
+ #define COLLADABU_HASH_NAMESPACE_OPEN std { namespace tr1
+ #define COLLADABU_HASH_NAMESPACE_CLOSE }
+ #define COLLADABU_HASH_FUN hash
+@@ -50,12 +50,12 @@
+ #define COLLADABU_HASH_FUN hash
+ #endif
+ #elif defined(__MINGW32__) || defined(__MINGW64__)
+- #include
+- #include
++ #include
++ #include
+
+- #define COLLADABU_HASH_MAP std::tr1::unordered_map
+- #define COLLADABU_HASH_MULTIMAP std::tr1::unordered_multimap
+- #define COLLADABU_HASH_SET std::tr1::unordered_set
++ #define COLLADABU_HASH_MAP std::unordered_map
++ #define COLLADABU_HASH_MULTIMAP std::unordered_multimap
++ #define COLLADABU_HASH_SET std::unordered_set
+ #define COLLADABU_HASH_NAMESPACE_OPEN std { namespace tr1
+ #define COLLADABU_HASH_NAMESPACE_CLOSE }
+ #define COLLADABU_HASH_FUN hash
+@@ -107,12 +107,12 @@
+ #define COLLADABU_HASH_NAMESPACE_CLOSE
+ #define COLLADABU_HASH_FUN hash
+ #else
+- #include
+- #include
++ #include
++ #include
+
+- #define COLLADABU_HASH_MAP std::tr1::unordered_map
+- #define COLLADABU_HASH_MULTIMAP std::tr1::unordered_multimap
+- #define COLLADABU_HASH_SET std::tr1::unordered_set
++ #define COLLADABU_HASH_MAP std::unordered_map
++ #define COLLADABU_HASH_MULTIMAP std::unordered_multimap
++ #define COLLADABU_HASH_SET std::unordered_set
+ #define COLLADABU_HASH_NAMESPACE_OPEN std { namespace tr1
+ #define COLLADABU_HASH_NAMESPACE_CLOSE }
+ #define COLLADABU_HASH_FUN hash
+diff --git a/common/libBuffer/include/CommonFWriteBufferFlusher.h b/common/libBuffer/include/CommonFWriteBufferFlusher.h
+index c7af45b2..fac4f133 100644
+--- a/common/libBuffer/include/CommonFWriteBufferFlusher.h
++++ b/common/libBuffer/include/CommonFWriteBufferFlusher.h
+@@ -15,12 +15,12 @@
+
+ #if (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) || (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__APPLE__))
+ #if defined(__GNUC__) && !defined(_LIBCPP_VERSION)
+-# include
++# include
+ #else
+ # include
+ #endif
+ #else
+-# include
++# include
+ #endif
+
+ #ifdef _LIBCPP_VERSION
+@@ -58,7 +58,7 @@ namespace Common
+ #else
+ typedef __int64 FilePosType;
+ #endif
+- typedef std::tr1::unordered_map MarkIdToFilePos;
++ typedef std::unordered_map MarkIdToFilePos;
+
+ public:
+ static const size_t DEFAUL_BUFFER_SIZE = 64*1024;
diff --git a/pyodide/meta.yaml b/pyodide/meta.yaml
new file mode 100644
index 0000000000..06c55eb97e
--- /dev/null
+++ b/pyodide/meta.yaml
@@ -0,0 +1,18 @@
+package:
+ name: ifcopenshell
+ version: 0.7.0
+
+source:
+ path: IfcOpenShell
+
+build:
+ script: |
+ python nix/build-all.py --without-hdf5 --without-opencollada --without-swig --without-pcre -v --wasm --py310 IfcOpenShell-Python
+ cp pyodide/setup.py .
+
+about:
+ home: http://ifcopenshell.org
+ license: LGPL-3.0-or-later
+ summary: |
+ IfcOpenShell is an open source (LGPL) software library for
+ working with the Industry Foundation Classes (IFC) file format.
diff --git a/pyodide/setup.py b/pyodide/setup.py
new file mode 100644
index 0000000000..67faf709cd
--- /dev/null
+++ b/pyodide/setup.py
@@ -0,0 +1,11 @@
+from setuptools import setup, find_packages
+
+setup(name='IfcOpenShell',
+ version='0.7.0',
+ description='IfcOpenShell is an open source (LGPL) software library for working with the Industry Foundation Classes (IFC) file format.',
+ author='Thomas Krijnen',
+ author_email='thomas@aecgeeks.com',
+ url='http://ifcopenshell.org',
+ packages=find_packages(),
+ package_data={'': ['*.so']},
+)
diff --git a/src/ifcwrap/CMakeLists.txt b/src/ifcwrap/CMakeLists.txt
index 150ac6363f..8caee5a956 100644
--- a/src/ifcwrap/CMakeLists.txt
+++ b/src/ifcwrap/CMakeLists.txt
@@ -67,20 +67,24 @@ endif()
# Try to find the Python interpreter to get the site-packages
# directory in which the wrapper can be installed.
FIND_PACKAGE(PythonInterp)
-IF(PYTHONINTERP_FOUND AND NOT "${PYTHON_EXECUTABLE}" STREQUAL "")
- IF (USERSPACE_PYTHON_PREFIX)
- EXECUTE_PROCESS(
- COMMAND ${PYTHON_EXECUTABLE} -c "import sys; import site; sys.stdout.write(site.USER_SITE)"
- OUTPUT_VARIABLE python_package_dir
- )
- ELSE ()
- EXECUTE_PROCESS(
- COMMAND ${PYTHON_EXECUTABLE} -c "import sys; from distutils.sysconfig import get_python_lib; sys.stdout.write(get_python_lib(1))"
- OUTPUT_VARIABLE python_package_dir
- )
- ENDIF()
- if (BUILD_PACKAGE)
- set(python_package_dir ${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_MAJOR}/dist-packages/)
+IF((PYTHONINTERP_FOUND AND NOT "${PYTHON_EXECUTABLE}" STREQUAL "") OR PYTHON_MODULE_INSTALL_DIR)
+ if (PYTHON_MODULE_INSTALL_DIR)
+ set(python_package_dir "${PYTHON_MODULE_INSTALL_DIR}")
+ else()
+ IF (USERSPACE_PYTHON_PREFIX)
+ EXECUTE_PROCESS(
+ COMMAND ${PYTHON_EXECUTABLE} -c "import sys; import site; sys.stdout.write(site.USER_SITE)"
+ OUTPUT_VARIABLE python_package_dir
+ )
+ ELSE ()
+ EXECUTE_PROCESS(
+ COMMAND ${PYTHON_EXECUTABLE} -c "import sys; from distutils.sysconfig import get_python_lib; sys.stdout.write(get_python_lib(1))"
+ OUTPUT_VARIABLE python_package_dir
+ )
+ ENDIF()
+ if (BUILD_PACKAGE)
+ set(python_package_dir ${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_MAJOR}/dist-packages/)
+ endif()
endif()
IF("${python_package_dir}" STREQUAL "")
MESSAGE(WARNING "Unable to locate Python site-package directory, unable to install the Python wrapper")
diff --git a/src/svgfill b/src/svgfill
index ac17050194..4d2aa7acf7 160000
--- a/src/svgfill
+++ b/src/svgfill
@@ -1 +1 @@
-Subproject commit ac1705019422ea012e8a5751cc5ed4639481b402
+Subproject commit 4d2aa7acf76cb8509ab3ba2961c34502adf3abe9