如何使用 Emscripten-1.38.31 (??) 编译 Boost-1.76.0

Posted

技术标签:

【中文标题】如何使用 Emscripten-1.38.31 (??) 编译 Boost-1.76.0【英文标题】:How to compile Boost-1.76.0 with Emscripten-1.38.31 (??) 【发布时间】:2021-02-15 02:18:28 【问题描述】:

我已经搜索了这个答案的高低,我认为它应该在现代环境中得到回答。我看到的大多数东西都是 2013 年或最迟 2015 年的,而 cmets 是 2019 年的。

首先,我使用的是 macOS 11.2 和最新版本的 xcode 12.4。

我从 git 克隆并安装了最新的(截至今天)用于 boost 和 emscripten 的存储库。

由于某些原因,在我的项目中尝试将 enscripten 标志集成到我的 CMakeLists.txt 文件中时,运行时出错

$ cmake .. 然后$ make

CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.17)
project(FernQuest) #emscripten version

if ($CMAKE_SYSTEM_NAME MATCHES "Emscripten")
    message(STATUS "using emscripten")
endif ()
if (NOT $CMAKE_SYSTEM_NAME MATCHES "Emscripten")
    message(STATUS "using cmake")
endif ()

#options
option(JS_ONLY "Compiles to native JS (No WASM)" OFF)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $CMAKE_CURRENT_SOURCE_DIR/out)

include_directories(.)
include_directories(/usr/local/include) #where boost in located

message(STATUS "finding boost!")
find_package(Boost 1.74.0 REQUIRED serialization system filesystem COMPONENTS serialization system filesystem)

if(Boost_FOUND)
    message(STATUS "found boost!")
endif()

include_directories($Boost_INCLUDE_DIR)
link_directories($Boost_LIBRARY_DIR)

if(NOT Boost_FOUND)
    message(FATAL_ERROR "Could not find boost!")
endif()

message(STATUS "setting sources")
SET(FQ_SRCS
    ../src/FernQuest.cpp
    ../src/Item.cpp
    ../src/Item.h
    ../src/Player.cpp
    ../src/Player.h
    ../src/Game.cpp
    ../src/Game.h
    ../src/QuestLog.cpp
    ../src/QuestLog.h)


SET(CMAKE_C_COMPILER emcc)
SET(CMAKE_CPP_COMPILER em++)


add_executable(FernQuest $FQ_SRCS)


if(Boost_FOUND)
  if(JS_ONLY)
    message(STATUS "Setting compilation target to native javascript")
    set(CMAKE_EXECUTABLE_SUFFIX ".js")
    set_target_properties(FernQuest PROPERTIES COMPILE_FLAGS "-s USE_BOOST_HEADERS=1" LINK_FLAGS "-s USE_BOOST_HEADERS=1 -s WASM=0 -s EXPORTED_FUNCTIONS='[_main]'")
  else(JS_ONLY)
    message(STATUS "Setting compilation target to WASM")
    set(CMAKE_EXECUTABLE_SUFFIX ".wasm.js")
    set_target_properties(FernQuest PROPERTIES COMPILE_FLAGS "-s USE_BOOST_HEADERS=1" LINK_FLAGS " -s USE_BOOST_HEADERS=1 -s WASM=1 -s EXPORTED_FUNCTIONS='[_main]'")
  endif(JS_ONLY)
endif()

错误:

-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/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: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- using cmake
-- finding boost!
-- Found Boost: /usr/local/lib/cmake/Boost-1.76.0/BoostConfig.cmake (found suitable version "1.76.0", minimum required is "1.74.0") found components: serialization system filesystem serialization system filesystem 
-- found boost!
-- setting sources
-- Setting compilation target to WASM
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/codiecottrell/Documents/FernQuest/emscripten/build
Scanning dependencies of target FernQuest
[ 16%] Building CXX object CMakeFiles/FernQuest.dir/Users/codiecottrell/Documents/FernQuest/src/FernQuest.cpp.o
clang: error: no such file or directory: 'USE_BOOST_HEADERS=1'
make[2]: *** [CMakeFiles/FernQuest.dir/Users/codiecottrell/Documents/FernQuest/src/FernQuest.cpp.o] Error 1
make[1]: *** [CMakeFiles/FernQuest.dir/all] Error 2
make: *** [all] Error 2

所以我读了,他们说要解决这个问题,你可以在下面使用它来实际使用 -DCMAKE_TOOLCHAIN_FILE 运行它:

$ emcmake cmake .. 然后$ emmake make

出现此错误:

configure: cmake .. -DCMAKE_TOOLCHAIN_FILE=/Users/codiecottrell/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR="/Users/codiecottrell/emsdk/node/14.15.5_64bit/bin/node"
-- using emscripten
-- finding boost!
CMake Error at /usr/local/Cellar/cmake/3.19.4/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:218 (message):
  Could NOT find Boost (missing: Boost_INCLUDE_DIR serialization system
  filesystem serialization system filesystem) (Required is at least version
  "1.74.0")
Call Stack (most recent call first):
  /usr/local/Cellar/cmake/3.19.4/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:582 (_FPHSA_FAILURE_MESSAGE)
  /usr/local/Cellar/cmake/3.19.4/share/cmake/Modules/FindBoost.cmake:2193 (find_package_handle_standard_args)
  CMakeLists.txt:21 (find_package)


-- Configuring incomplete, errors occurred!
See also "/Users/codiecottrell/Documents/FernQuest/emscripten/build/CMakeFiles/CMakeOutput.log".
make: make
-- using emscripten
-- finding boost!
CMake Error at /usr/local/Cellar/cmake/3.19.4/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:218 (message):
  Could NOT find Boost (missing: Boost_INCLUDE_DIR serialization system
  filesystem serialization system filesystem) (Required is at least version
  "1.74.0")
Call Stack (most recent call first):
  /usr/local/Cellar/cmake/3.19.4/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:582 (_FPHSA_FAILURE_MESSAGE)
  /usr/local/Cellar/cmake/3.19.4/share/cmake/Modules/FindBoost.cmake:2193 (find_package_handle_standard_args)
  CMakeLists.txt:21 (find_package)


-- Configuring incomplete, errors occurred!
See also "/Users/codiecottrell/Documents/FernQuest/emscripten/build/CMakeFiles/CMakeOutput.log".
make: *** [cmake_check_build_system] Error 1

我的问题: 似乎 enscripten 在通过自己的方式运行它时无法找到提升,但是 cmake 可以清楚地找到它。正如我在两个文档中所读到的,还支持通过 emscripten 运行 boost,但是没有明确的方法。这是什么方式,我哪里出错了?我会继续排查问题

编辑

刚试过$ emconfigure ./b2 toolset=gcc --prefix=/usr/local/B2

它并没有改变任何东西

【问题讨论】:

您似乎将-s USE_BOOST_HEADERS=1 传递给C++ 编译器。为什么? 我刚刚看到它在其他几个地方做了这些,我是设置 cmakes 的新手 【参考方案1】:

如果您使用 emscripten 进行构建,那么您 mac 上的库(cmake 正在搜索的地方)将无法工作;您需要静态编译它们。 我建议尝试不使用 CMake 构建您的项目。 如果您的项目只使用 boost 标头(而不是库),那么这样的事情可能会起作用:

$ em++ ../src/*.cpp -o index.html -s USE_BOOST_HEADERS=1

否则,您还需要编译 Boost。一旦你完成了这些并且你有一个libboost.a 文件,你可以像这样编译你的程序:

$ em++ ../src/*.cpp -c -s USE_BOOST_HEADERS=1

然后链接它:

$ em++ *.o /path/to/libboost.a -o index.html

当然,根据您使用的其他库,您需要调整这些命令。但总体思路是将所有依赖项编译成静态归档 (.a) 文件,然后将它们编译在一起以获得生成的 .html(或 .js 或 .wasm)文件。 阅读有关compiling with emcc 的更多信息。

【讨论】:

以上是关于如何使用 Emscripten-1.38.31 (??) 编译 Boost-1.76.0的主要内容,如果未能解决你的问题,请参考以下文章

如果加入条件,我该如何解决。如果使用字符串连接,我如何使用

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?