使用Emscripten编译含CGAL的C++项目至Wasm失败求助
问题描述
我克隆了一个依赖CGAL的C++项目,尝试用Emscripten将其编译为WebAssembly格式。单独用cmake ../在自建build目录中能成功配置,但执行emcmake cmake ../时编译失败,错误提示找不到CGAL的配置文件CGALConfig.cmake或cgal-config.cmake。
成功的本地CMake配置日志
cmake ../ (at build folder which make by myself , it is success)
-- The C compiler identification is GNU 11.4.0 -- The CXX compiler identification is GNU 11.4.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done CMake Warning at /usr/lib/x86_64-linux-gnu/cmake/CGAL/CGALConfig.cmake:92 (message): CGAL_DATA_DIR cannot be deduced, set the variable CGAL_DATA_DIR to set the default value of CGAL::data_file_path() Call Stack (most recent call first): CMakeLists.txt:4 (find_package) -- Using header-only CGAL -- Targetting Unix Makefiles -- Using /usr/bin/c++ compiler. -- Found GMP: /usr/lib/x86_64-linux-gnu/libgmp.so -- Found MPFR: /usr/lib/x86_64-linux-gnu/libmpfr.so -- Found Boost: /usr/lib/x86_64-linux-gnu/cmake/Boost-1.74.0/BoostConfig.cmake (found suitable version "1.74.0", minimum required is "1.48") -- Boost include dirs: /usr/include -- Boost libraries: -- Looking for pthread.h -- Looking for pthread.h - found -- Performing Test CMAKE_HAVE_LIBC_PTHREAD -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success -- Found Threads: TRUE -- Using gcc version 4 or later. Adding -frounding-math -- Build type: -- USING CXXFLAGS = ' ' -- USING EXEFLAGS = ' ' CMake Warning at /usr/lib/x86_64-linux-gnu/cmake/CGAL/CGAL_enable_end_of_configuration_hook.cmake:99 (message): ======================================================================= CGAL performance notice: The variable CMAKE_BUILD_TYPE is set to "". For performance reasons, you should set CMAKE_BUILD_TYPE to "Release". Set CGAL_DO_NOT_WARN_ABOUT_CMAKE_BUILD_TYPE to TRUE if you want to disable this warning. ======================================================================= Call Stack (most recent call first): CMakeLists.txt:9223372036854775807 (CGAL_run_at_the_end_of_configuration) -- Configuring done -- Generating done -- Build files have been written to: /home/lyciih/github/CGAL_triangulation_demo/build
Emscripten编译错误日志
emcmake cmake ../
configure: cmake ../ -DCMAKE_TOOLCHAIN_FILE=/usr/share/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/usr/bin/node;--experimental-wasm-threads CMake Error at CMakeLists.txt:4 (find_package): By not providing "FindCGAL.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "CGAL", but CMake did not find one. Could not find a package configuration file provided by "CGAL" with any of the following names: CGALConfig.cmake cgal-config.cmake Add the installation prefix of "CGAL" to CMAKE_PREFIX_PATH or set "CGAL_DIR" to a directory containing one of the above files. If "CGAL" provides a separate development package or SDK, be sure it has been installed. -- Configuring incomplete, errors occurred! See also "/home/lyciih/github/CGAL_triangulation_demo/build/CMakeFiles/CMakeOutput.log". emcmake: error: 'cmake ../ -DCMAKE_TOOLCHAIN_FILE=/usr/share/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/usr/bin/node;--experimental-wasm-threads' failed (returned 1)
解决方案
1. 先指定CGAL配置文件路径
普通CMake能找到系统安装的CGAL,是因为默认搜索了/usr/lib/x86_64-linux-gnu/cmake/CGAL/目录。交叉编译时需要显式告诉Emscripten的CMake工具链这个路径:
emcmake cmake ../ -DCGAL_DIR=/usr/lib/x86_64-linux-gnu/cmake/CGAL/
执行后大概率会遇到GMP/MPFR找不到的新错误——系统安装的GMP/MPFR是x86架构的,无法被Emscripten的交叉编译环境使用,需要为WebAssembly编译这两个依赖库。
2. 编译Emscripten版本的GMP和MPFR
编译GMP
- 下载GMP源码并解压,进入源码目录:
wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz tar -xf gmp-6.3.0.tar.xz cd gmp-6.3.0 - 用Emscripten配置编译:
emconfigure ./configure --host=asmjs-unknown-emscripten --prefix=$HOME/emsdk/ports/gmp emmake make -j$(nproc) emmake make install
编译MPFR
- 下载MPFR源码并解压,进入源码目录:
wget https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz tar -xf mpfr-4.2.1.tar.xz cd mpfr-4.2.1 - 用Emscripten配置编译(依赖已编译好的GMP):
emconfigure ./configure --host=asmjs-unknown-emscripten --with-gmp=$HOME/emsdk/ports/gmp --prefix=$HOME/emsdk/ports/mpfr emmake make -j$(nproc) emmake make install
3. 带依赖路径执行Emscripten CMake配置
现在在cmake命令中同时指定CGAL、GMP、MPFR的路径:
emcmake cmake ../ \ -DCGAL_DIR=/usr/lib/x86_64-linux-gnu/cmake/CGAL/ \ -DGMP_INCLUDE_DIR=$HOME/emsdk/ports/gmp/include \ -DGMP_LIBRARY=$HOME/emsdk/ports/gmp/lib/libgmp.a \ -DMPFR_INCLUDE_DIR=$HOME/emsdk/ports/mpfr/include \ -DMPFR_LIBRARY=$HOME/emsdk/ports/mpfr/lib/libmpfr.a \ -DCMAKE_BUILD_TYPE=Release
备选方案:编译Emscripten版本的CGAL
如果上面的方法仍有问题,可以直接编译针对WebAssembly的CGAL源码:
- 克隆CGAL源码:
git clone https://github.com/CGAL/cgal.git cd cgal mkdir build-emscripten && cd build-emscripten - 用Emscripten编译CGAL:
emcmake cmake ../ \ -DCMAKE_BUILD_TYPE=Release \ -DGMP_INCLUDE_DIR=$HOME/emsdk/ports/gmp/include \ -DGMP_LIBRARY=$HOME/emsdk/ports/gmp/lib/libgmp.a \ -DMPFR_INCLUDE_DIR=$HOME/emsdk/ports/mpfr/include \ -DMPFR_LIBRARY=$HOME/emsdk/ports/mpfr/lib/libmpfr.a emmake make -j$(nproc) - 在你的项目中指定CGAL_DIR为编译后的目录:
emcmake cmake ../ \ -DCGAL_DIR=/path/to/cgal/build-emscripten \ -DGMP_INCLUDE_DIR=$HOME/emsdk/ports/gmp/include \ -DGMP_LIBRARY=$HOME/emsdk/ports/gmp/lib/libgmp.a \ -DMPFR_INCLUDE_DIR=$HOME/emsdk/ports/mpfr/include \ -DMPFR_LIBRARY=$HOME/emsdk/ports/mpfr/lib/libmpfr.a \ -DCMAKE_BUILD_TYPE=Release
注意事项
- 确保已正确激活Emscripten环境:
source $HOME/emsdk/emsdk_env.sh(路径根据你的emsdk安装位置调整) - 如果项目依赖Boost,同样需要确认Boost是否能被Emscripten找到,或者编译Emscripten版本的Boost
内容的提问来源于stack exchange,提问作者YI-CHENG LI
相关产品推荐
相关产品推荐

