使用 Emscripten 编译时如何正确链接 Boost?
main.cpp
:
#include <boost/filesystem.hpp>
int main() {
boost::filesystem::exists("file.txt");
}
编译并链接:
> em++ main.cpp --use-ports=boost_headers -sUSE_BOOST_HEADERS=1 -lboost_headers
wasm-ld: error: /tmp/emscripten_temp_u68f6vxm/main_0.o: undefined symbol: boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)
em++: error: '/home/ubuntu/tmp/emscripten/emsdk/upstream/bin/wasm-ld -o a.out.wasm /tmp/emscripten_temp_u68f6vxm/main_0.o -L/home/ubuntu/tmp/emscripten/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten /home/ubuntu/tmp/emscripten/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libboost_headers.a -lGL-getprocaddr -lal -lhtml5 -lstubs-debug -lnoexit -lc-debug -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-debug-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmpv1sq5rj0libemscripten_js_symbols.so --strip-debug --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=stackAlloc --export=stackSave --export=stackRestore --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --initial-memory=16777216 --max-memory=16777216 --no-entry --stack-first --table-base=1' failed (returned 1)
与
-lboost_filesystem
:
wasm-ld: error: unable to find library -lboost_filesystem
git clone --recursive --branch=boost-1.83.0 --depth=1 https://github.com/boostorg/boost.git
cd boost
# Without specifying a toolset, it shows the help
# When specifying --with-toolset=emscripten, it says toolset emscripten not recognized
# b2 is generated --with-toolset=gcc
./bootstrap.sh --with-toolset=gcc
# from https://stackoverflow.com/a/47751199/16847511
./b2 toolset=emscripten
最后一个命令(
./b2 toolset=emscripten
)给出错误:
emcc: warning: .bc output file suffix used without -flto or -emit-llvm. Consider using .o extension since emcc will output an object file, not a bitcode file [-Wemcc]
emscripten.archive bin.v2/libs/log/build/emscripten-3.1.55/release/link-static/threading-multi/visibility-hidden/libboost_log.bc
bin.v2/libs/log/build/emscripten-3.1.55/release/link-static/threading-multi/visibility-hidden/attribute_name.bc:1:2: error: expected top-level entity
emconfigure ./b2 toolset=gcc
可以工作,但构建的是常规版本,不适合 Emscripten。以我的第一个代码片段为例:
> em++ main.cpp --use-ports=boost_headers -sUSE_BOOST_HEADERS=1 -lboost_headers -lboost_filesystem -L/tmp/boost/stage/lib
wasm-ld: warning: /tmp/boost/stage/lib/libboost_filesystem.a: archive member 'codecvt_error_category.o' is neither Wasm object file nor LLVM bitcode
wasm-ld: warning: /tmp/boost/stage/lib/libboost_filesystem.a: archive member 'exception.o' is neither Wasm object file nor LLVM bitcode
wasm-ld: warning: /tmp/boost/stage/lib/libboost_filesystem.a: archive member 'directory.o' is neither Wasm object file nor LLVM bitcode
wasm-ld: warning: /tmp/boost/stage/lib/libboost_filesystem.a: archive member 'operations.o' is neither Wasm object file nor LLVM bitcode
wasm-ld: warning: /tmp/boost/stage/lib/libboost_filesystem.a: archive member 'path.o' is neither Wasm object file nor LLVM bitcode
wasm-ld: warning: /tmp/boost/stage/lib/libboost_filesystem.a: archive member 'path_traits.o' is neither Wasm object file nor LLVM bitcode
wasm-ld: warning: /tmp/boost/stage/lib/libboost_filesystem.a: archive member 'portability.o' is neither Wasm object file nor LLVM bitcode
wasm-ld: warning: /tmp/boost/stage/lib/libboost_filesystem.a: archive member 'unique_path.o' is neither Wasm object file nor LLVM bitcode
wasm-ld: warning: /tmp/boost/stage/lib/libboost_filesystem.a: archive member 'utf8_codecvt_facet.o' is neither Wasm object file nor LLVM bitcode
wasm-ld: error: /tmp/emscripten_temp_k9_q4uwl/simple-boost_0.o: undefined symbol: boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)
em++: error: '/home/ubuntu/tmp/emscripten/emsdk/upstream/bin/wasm-ld -o a.out.wasm /tmp/emscripten_temp_k9_q4uwl/simple-boost_0.o /home/ubuntu/tmp/emscripten/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libboost_headers.a /tmp/boost/stage/lib/libboost_filesystem.a -L/tmp/boost/stage/lib -L/home/ubuntu/tmp/emscripten/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten /home/ubuntu/tmp/emscripten/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libboost_headers.a -lGL-getprocaddr -lal -lhtml5 -lstubs-debug -lnoexit -lc-debug -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-debug-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmp2dceaguelibemscripten_js_symbols.so --strip-debug --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=stackAlloc --export=stackSave --export=stackRestore --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --initial-memory=16777216 --max-memory=16777216 --no-entry --stack-first --table-base=1' failed (returned 1)
尝试使用
develop
分支后,它对我来说效果很好。
根据您的请求,我使用 1.83.0 分支结帐进行了验证,果然,我遇到了构建错误。
所以我建议您构建自己的 1.84.0(或
develop
)版本,该版本显然已修复该问题。
当然,不要使用
--use-ports
中的标题。相反,请使用您自己结账时的标题:
em++ main.cpp -I ~/custom/boost/ -L ~/custom/boost/stage/lib/ -lboost_filesystem
-I
标志告诉编译器在哪里可以找到包含。
-L
标志告诉链接器在哪里可以找到共享库。
这是使用我的
develop
构建(报告为 1.85.0),它运行良好: