diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index d1833f4..ba137f9 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -8,10 +8,10 @@ jobs:
   build:
     strategy:
       matrix:
-        os: [windows-2022, macos-12, ubuntu-22.04]
+        os: [windows-2022, macos-15, ubuntu-22.04]
     runs-on: ${{ matrix.os }}
     steps:
-      - uses: secondlife/action-autobuild@v4
+      - uses: secondlife/action-autobuild@v5
   release:
     needs: build
     runs-on: [ubuntu-latest]
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b1c1993..91313e7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,14 +1,25 @@
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
-set(COLLADA14_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/1.4)
-set(COLLADA15_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/1.5)
+cmake_minimum_required(VERSION 3.17)
+project(colladadom)
+
+include(FindPkgConfig)
+
+find_package(Boost REQUIRED CONFIG)
+pkg_check_modules(LIBXML2 libxml-2.0)
+pkg_check_modules(MINIZIP minizip)
+pkg_check_modules(ZLIB zlib)
+
+set(COLLADA_DOM_SOVERSION "0")
+set(COLLADA_DOM_VERSION "2.3")
+
 file(GLOB dae_files ${CMAKE_CURRENT_SOURCE_DIR}/src/dae/*.cpp)
 file(GLOB libxmlplugin_files ${CMAKE_CURRENT_SOURCE_DIR}/src/modules/LIBXMLPlugin/*.cpp)
 file(GLOB stddatabase_files ${CMAKE_CURRENT_SOURCE_DIR}/src/modules/STLDatabase/*.cpp)
 file(GLOB stderrplugin_files ${CMAKE_CURRENT_SOURCE_DIR}/src/modules/stdErrPlugin/*.cpp)
 
 set(COLLADA_BASE_SOURCES ${dae_files} ${libxmlplugin_files} ${stddatabase_files} ${stderrplugin_files})
-set(COLLADA_LIBS minizip ${ZLIB_LIBRARIES} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY})
-set(COLLADA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} ${Boost_CFLAGS} -DDOM_INCLUDE_LIBXML")
+set(COLLADA_LIBS ${LIBXML2_LIBRARIES} ${MINIZIP_LIBRARIES} ${ZLIB_LIBRARIES} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_REGEX_LIBRARY})
+list(JOIN MINIZIP_CFLAGS " " VAR_MINIZIP_CFLAGS)
+set(COLLADA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} ${VAR_MINIZIP_CFLAGS} ${Boost_CFLAGS} -DDOM_INCLUDE_LIBXML")
 
 if( OPT_COLLADA15 )
   add_subdirectory(src/1.5)
@@ -17,8 +28,8 @@ if( OPT_COLLADA14 )
   add_subdirectory(src/1.4)
 endif()
 
-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/1.4 DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE)
-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/1.5 DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE)
-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/dae DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE)
-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/modules DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE)
-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/dae.h ${CMAKE_CURRENT_SOURCE_DIR}/include/dae.h DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR})
+# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/1.4 DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE)
+# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/1.5 DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE)
+# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/dae DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE)
+# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/modules DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR} PATTERN ".svn" EXCLUDE PATTERN ".~" EXCLUDE)
+# install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/dae.h ${CMAKE_CURRENT_SOURCE_DIR}/include/dae.h DESTINATION ${COLLADA_DOM_INCLUDE_INSTALL_DIR})
diff --git a/Makefile b/Makefile
index f317973..441caf1 100755
--- a/Makefile
+++ b/Makefile
@@ -59,7 +59,7 @@ ifneq ($(shell uname -p | grep -i powerpc),)
 nativeArch := ppc
 endif
 
-# arch: x86 (or i386), x64 (or x86_64), ppc, ppc64
+# arch: x86 (or i386), x64 (or x86_64), ppc, ppc64, arm64
 arch ?= i386
 
 # project: 'dom', 'domTest', or 'all'
@@ -103,7 +103,7 @@ $(error Invalid setting os=$(os))
 endif
 
 archs := $(sort $(subst i386,x86,$(arch)))
-ifneq ($(filter-out x86 ppc x86_64,$(archs)),)
+ifneq ($(filter-out x86 ppc x86_64 arm64,$(archs)),)
 $(error Invalid setting arch=$(arch))
 endif
 
diff --git a/autobuild.xml b/autobuild.xml
index 21a28c7..96436a9 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -21,11 +21,11 @@
             archive
             
             name
             darwin64
@@ -35,11 +35,11 @@
             archive
             
             name
             linux64
@@ -49,11 +49,11 @@
             archive
             
             name
             windows64
@@ -81,11 +81,11 @@
             archive
             
             name
             darwin64
@@ -95,11 +95,11 @@
             archive
             
             name
             linux64
@@ -109,18 +109,18 @@
             archive
             
             name
             windows64
           
         
         version
-        2.13.3-r1
+        2.13.5-r2
       
       minizip-ng
       
         
         version
-        4.0.7-r1
+        4.0.7-r3
       
       zlib-ng
       
@@ -205,11 +205,11 @@
             archive
             
               hash
-              3a6593c71c59ace76d1349483759fcde4b719a76
+              e363e3b889c52fda7601d7aeaa9832307034651e
               hash_algorithm
               sha1
               url
-              https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.1-r2/zlib_ng-2.2.1-r2-darwin64-10324415171.tar.zst
+              https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-darwin64-13183604450.tar.zst
             
             name
             darwin64
@@ -219,11 +219,11 @@
             archive
             
               hash
-              fbadeb0b8c771cb06c0055c9fab6d40c6764dacd
+              3cdd52f7fb3691789d50f0b40ed6f5642321ff32
               hash_algorithm
               sha1
               url
-              https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.1-r2/zlib_ng-2.2.1-r2-linux64-10324415171.tar.zst
+              https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-linux64-13183604450.tar.zst
             
             name
             linux64
@@ -233,18 +233,18 @@
             archive
             
               hash
-              0094031715662be626f5106ff6c814f4fc3dacfa
+              e802a28139328bb2421ad39e13d996d350d8106d
               hash_algorithm
               sha1
               url
-              https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.1-r2/zlib_ng-2.2.1-r2-windows64-10324415171.tar.zst
+              https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-windows64-13183604450.tar.zst
             
             name
             windows64
           
         
         version
-        2.2.1-r2
+        2.2.3-dev0.g8aa13e3.d20250206
       
     
     package_description
diff --git a/build-cmd.sh b/build-cmd.sh
index ee706ed..df5fa53 100755
--- a/build-cmd.sh
+++ b/build-cmd.sh
@@ -96,7 +96,7 @@ case "$AUTOBUILD_PLATFORM" in
                 then
                     "build/$versub/domTest.exe" -all
                 else
-                    # 64 bit exe ends up in different location to 32 bit hard coded 
+                    # 64 bit exe ends up in different location to 32 bit hard coded
                     # path to data directory - source code suggests it looks in a dir
                     # called domTestData first so we make one
                     mkdir -p "$projdir/x64/Release/domTestData"
@@ -111,7 +111,7 @@ case "$AUTOBUILD_PLATFORM" in
         libname="libcollada${collada_shortver}dom${dom_shortver}-s.lib"
         if [ "$AUTOBUILD_ADDRSIZE" = 32 ]
             then cp -a "build/$versub/$libname" "$stage"/lib/release/
-            else cp -a "$projdir/x64/Release/$libname" "$stage"/lib/release/ 
+            else cp -a "$projdir/x64/Release/$libname" "$stage"/lib/release/
         fi
     ;;
 
@@ -126,15 +126,13 @@ case "$AUTOBUILD_PLATFORM" in
         # repo                  root                run_tests               suffix
         export MACOSX_DEPLOYMENT_TARGET="$LL_BUILD_DARWIN_DEPLOY_TARGET"
 
-        opts="${TARGET_OPTS:--arch $AUTOBUILD_CONFIGURE_ARCH $LL_BUILD_RELEASE}"
+        opts="${TARGET_OPTS:--arch arm64 -arch x86_64 $LL_BUILD_RELEASE}"
 
         nproc=$(sysctl -n hw.physicalcpu)
 
         libdir="$top/stage"
         mkdir -p "$libdir"/lib/release
 
-        make clean arch="$AUTOBUILD_CONFIGURE_ARCH" # Hide 'arch' env var
-
         # Without the -Wno-etc flag, incredible spam is produced
         make \
             conf=release \
@@ -142,7 +140,7 @@ case "$AUTOBUILD_PLATFORM" in
             CFLAGS="$opts" \
             CXXFLAGS="$opts -Wno-unused-local-typedef" \
             LDFLAGS="-Wl,-headerpad_max_install_names" \
-            arch="$AUTOBUILD_CONFIGURE_ARCH" \
+            arch="x86_64 arm64" \
             printCommands=yes \
             printMessages=yes
 
diff --git a/include/dae/daeArray.h b/include/dae/daeArray.h
index 81e0fa7..941257e 100644
--- a/include/dae/daeArray.h
+++ b/include/dae/daeArray.h
@@ -415,7 +415,7 @@ public:
 	 * @param other A reference to the other array.
 	 * @return true if the arrays are equal, false otherwise.
 	 */
-	bool operator==(const daeTArray& other) {
+	bool operator==(const daeTArray& other) const {
 		if (getCount() != other.getCount())
 			return false;
 		for (size_t i = 0; i < getCount(); i++)
diff --git a/make/common.mk b/make/common.mk
index ea87d36..6105abc 100644
--- a/make/common.mk
+++ b/make/common.mk
@@ -15,12 +15,14 @@ ifeq ($(conf),debug)
 ccFlags += -g -D_DEBUG
 debugSuffix := -d
 else
-ccFlags += -O2 -DNDEBUG
+ccFlags += -O3 -DNDEBUG
 debugSuffix :=
 endif
 
 ifeq ($(arch),x86_64)
 archsupport := -x64
+else ifeq ($(arch),arm64)
+archsupport := -a64
 else
 archsupport :=
 endif
diff --git a/make/rules.mk b/make/rules.mk
index eb55234..1b976a8 100644
--- a/make/rules.mk
+++ b/make/rules.mk
@@ -41,7 +41,7 @@ ifneq ($(obj),)
 # any values we use in rule commands. This is the reason for all the target-specific variables.
 $(obj): cc := $(cc)
 $(obj): ccFlags := $(ccFlags)
-$(obj): ccFlagsNoArch := $(filter-out -arch ppc ppc64 i386 x86_64,$(ccFlags))
+$(obj): ccFlagsNoArch := $(filter-out -arch ppc ppc64 i386 x86_64 arm64,$(ccFlags))
 $(obj): includeOpts := $(includeOpts)
 
 # Call createObjRule with a source file path
diff --git a/make/rulesC.mk b/make/rulesC.mk
index 15b1e6a..023814d 100644
--- a/make/rulesC.mk
+++ b/make/rulesC.mk
@@ -52,7 +52,7 @@ ifneq ($(obj),)
 #$(obj): cc := $(cc)
 $(obj): cc := $(CC)
 $(obj): ccFlags := $(ccFlags)
-$(obj): ccFlagsNoArch := $(filter-out -arch ppc ppc64 i386 x86_64,$(ccFlags))
+$(obj): ccFlagsNoArch := $(filter-out -arch ppc ppc64 i386 x86_64 arm64,$(ccFlags))
 $(obj): includeOpts := $(includeOpts)
 
 # Call createObjRule with a source file path
diff --git a/src/1.4/CMakeLists.txt b/src/1.4/CMakeLists.txt
index 17fbaea..d0d5939 100644
--- a/src/1.4/CMakeLists.txt
+++ b/src/1.4/CMakeLists.txt
@@ -1,10 +1,31 @@
 file(GLOB dom_files ${CMAKE_CURRENT_SOURCE_DIR}/dom/*.cpp)
-include_directories(${COLLADA14_INCLUDE_DIR})
-add_library(collada14dom SHARED ${COLLADA_BASE_SOURCES} ${dom_files})
+add_library(collada14dom STATIC ${COLLADA_BASE_SOURCES} ${dom_files})
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+  target_compile_options(collada14dom PRIVATE
+          "-pedantic" "-Wno-error=unused-result" "-Wno-cast-user-defined" "-Wno-nonnull")
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+  target_compile_options(collada14dom PRIVATE
+          "-Wno-error=unused-result"
+  )
+endif()
+target_include_directories(collada14dom PRIVATE
+	${colladadom_SOURCE_DIR}/include
+	${colladadom_SOURCE_DIR}/include/1.4
+	${Boost_INCLUDE_DIRS}
+	${LIBXML2_INCLUDE_DIRS}
+	${MINIZIP_INCLUDE_DIRS}
+	${ZLIB_INCLUDE_DIRS}
+)
+target_link_directories(collada14dom INTERFACE
+	${Boost_LIBRARY_DIRS}
+	${LIBXML2_LIBRARY_DIRS}
+	${MINIZIP_LIBRARY_DIRS}
+	${ZLIB_LIBRARY_DIRS}
+)
 target_link_libraries(collada14dom ${COLLADA_LIBS})
 set_target_properties(collada14dom PROPERTIES
   COMPILE_FLAGS "${COLLADA_COMPILE_FLAGS}"
   CLEAN_DIRECT_OUTPUT 1
   SOVERSION ${COLLADA_DOM_SOVERSION}
   VERSION ${COLLADA_DOM_VERSION})
-install(TARGETS collada14dom DESTINATION lib${LIB_SUFFIX})
+# install(TARGETS collada14dom DESTINATION ${COLLADA_DOM_LIBS_INSTALL_DIR})
diff --git a/src/1.5/CMakeLists.txt b/src/1.5/CMakeLists.txt
index e061a01..fb73a70 100644
--- a/src/1.5/CMakeLists.txt
+++ b/src/1.5/CMakeLists.txt
@@ -1,10 +1,10 @@
 file(GLOB dom_files ${CMAKE_CURRENT_SOURCE_DIR}/dom/*.cpp)
 include_directories(${COLLADA15_INCLUDE_DIR})
-add_library(collada15dom SHARED ${COLLADA_BASE_SOURCES} ${dom_files})
+add_library(collada15dom STATIC ${COLLADA_BASE_SOURCES} ${dom_files})
 target_link_libraries(collada15dom ${COLLADA_LIBS})
 set_target_properties(collada15dom PROPERTIES
   COMPILE_FLAGS "${COLLADA_COMPILE_FLAGS}"
   CLEAN_DIRECT_OUTPUT 1
   SOVERSION ${COLLADA_DOM_SOVERSION}
   VERSION ${COLLADA_DOM_VERSION})
-install(TARGETS collada15dom DESTINATION lib${LIB_SUFFIX})
+install(TARGETS collada15dom DESTINATION ${COLLADA_DOM_LIBS_INSTALL_DIR})
diff --git a/src/dae/daeMetaElement.cpp b/src/dae/daeMetaElement.cpp
index 55a57f5..5dc4657 100644
--- a/src/dae/daeMetaElement.cpp
+++ b/src/dae/daeMetaElement.cpp
@@ -107,8 +107,8 @@ daeMetaElement::addContentsOrder(daeInt offset)
 	meaa->setOffset(offset);
 	meaa->setContainer( this);
 
-    if (_metaContentsOrder)
-        delete _metaContentsOrder;
+	if (_metaContentsOrder)
+		delete _metaContentsOrder;
 
 	_metaContentsOrder = meaa;
 }
@@ -121,8 +121,8 @@ void daeMetaElement::addCMDataArray(daeInt offset, daeUInt numChoices)
 	meaa->setOffset(offset);
 	meaa->setContainer( this);
 
-    if (_metaCMData)
-        delete _metaCMData;
+	if (_metaCMData)
+		delete _metaCMData;
 
 	_metaCMData = meaa;
 
@@ -175,7 +175,7 @@ daeMetaElement::appendAttribute(daeMetaAttribute* attr)
 	else
 		_metaAttributes.append(attr);
 
-	if ((attr->getName() != NULL) &&
+	if ((daeString(attr->getName()) != NULL) &&
 		(strcmp(attr->getName(),"id") == 0)) {
 		_metaID = attr;
 		_isTrackableForQueries = true;
diff --git a/src/dae/daeUtils.cpp b/src/dae/daeUtils.cpp
index 682692c..71b1f12 100644
--- a/src/dae/daeUtils.cpp
+++ b/src/dae/daeUtils.cpp
@@ -19,6 +19,8 @@
 
 #ifndef NO_BOOST
 #include  // THIS WAS NOT COMMENTED.
+#include 
+#include 
 #endif
 
 #include  // for tmpnam
@@ -118,7 +120,7 @@ list cdom::makeStringList(const char* s, ...) {
 	va_end(args);
 	return result;
 }
-#endif 0
+#endif // 0
 
 string cdom::getCurrentDir() {
 #ifdef __CELLOS_LV2__
@@ -154,7 +156,7 @@ char cdom::getFileSeparator() {
 const string& cdom::getSystemTmpDir() {
 #ifdef WIN32
     static string tmpDir = string(getenv("TMP")) + getFileSeparator();
-#elif defined(__linux__) || defined(__linux)
+#elif defined(__linux__) || defined(__linux) || defined(__FreeBSD__)
     static string tmpDir = "/tmp/";
 #elif defined __APPLE_CC__
 static string tmpDir = string(getenv("TMPDIR"));
@@ -169,11 +171,16 @@ static string tmpDir = string(getenv("TMPDIR"));
 string cdom::getRandomFileName() {
     std::string randomSegment;
     // have to createa a buffer in order to make it multi-thread safe
+#ifdef NO_BOOST
     std::string tmpbuffer; tmpbuffer.resize(L_tmpnam*2+1);
     std::string tmp(tmpnam(&tmpbuffer[0]));
+#else
+    boost::uuids::uuid uuid = boost::uuids::random_generator()();
+    std::string tmp(boost::uuids::to_string(uuid));
+#endif
 #ifdef WIN32
     randomSegment = tmp.substr(tmp.find_last_of('\\')+1);
-#elif defined(__linux__) || defined(__linux)
+#elif defined(__linux__) || defined(__linux) || defined(__FreeBSD__)
     randomSegment = tmp.substr(tmp.find_last_of('/')+1);
 #elif defined __APPLE_CC__
 	randomSegment = tmp.substr(tmp.find_last_of('/')+1);