c++ - CMake 制作的 Emscripten 库无法链接

标签 c++ makefile cmake emscripten gdcm

我正在使用 Grassroot Dicom 查看器版本 2.8.9 在 Windows 10 64 位平台上编译成 Emscripten 库 bc。

我按照此 website 中的说明进行操作

emconfigure cmake .
emmake make VERBOSE=1

之后我得到了以 .a 而不是 .bc 结尾的库文件,类似于

libgdcmcharls.a libgdcmCommon.a libgdcmDICT.a ....

当我查看它开头的每个静态库文件的汇编代码时

!拱./

代替

BC

如教程中所述 website注意

Some build systems may not properly emit bitcode using the above procedure, and you may see is not valid bitcode warnings. You can run file to check if a file contains bitcode (also you can manually check if the contents start with BC). It is also worth running emmake make VERBOSE=1 which will print out the commands it runs - you should see emcc being used, and not the native system compiler. If emcc is not used, you may need to modify the configure or cmake scripts.

我认为这是我无法生成内容以 BC 开头的库的问题,但我得到了!拱./?

当然那些文件不能从 emcc 链接(找不到引用错误)

error: undefined symbol: _ZN4gdcm11ImageReader8GetImageEv
error: undefined symbol: _ZN4gdcm11ImageReaderC1Ev
error: undefined symbol: _ZN4gdcm11ImageReaderD1Ev
error: undefined symbol: _ZN4gdcm5Trace14GetErrorStreamE

于是我根据this修改了GDCM CMakefile.txt

if (EMSCRIPTEN)
    set(CMAKE_AR "emcc" CACHE)
    set(CMAKE_STATIC_LIBRARY_SUFFIX ".bc")
    set(CMAKE_C_CREATE_STATIC_LIBRARY "<CMAKE_AR> -o <TARGET> <LINK_FLAGS> <OBJECTS>")
    set(CMAKE_CXX_CREATE_STATIC_LIBRARY "<CMAKE_AR> -o <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()

然而,这并没有什么帮助。 “make”仍然生成 .a 库文件

我编译代码的命令如下;我还将所有 .a 文件复制到与 main.cpp 相同的文件夹

emcc -std=c++17 -O3 -s WASM=1  -s USE_WEBGL2=1 -s FULL_ES3=1 -s ALLOW_MEMORY_GROWTH=1 -o hello.html  -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']" --no-heap-copy libgdcmcharls.a libgdcmCommon.a libgdcmDICT.a libgdcmDSED.a libgdcmexpat.a libgdcmIOD.a libgdcmjpeg12.a libgdcmjpeg16.a libgdcmjpeg8.a libgdcmMEXD.a libgdcmMSFF.a libgdcmopenjp2.a libgdcmzlib.a libgdcmuuid.a libsocketxx.a main.cpp ...........

link是我的 GDCM 2.8.9 库文件。在Windows10中编译使用 emcmake cmake 最后是 emmake make(基于 mingw32-make)。

这是调用 emconfigure cmake 后我的 CMakeCXXCompiler.cmake。

set(CMAKE_CXX_COMPILER "C:/workspace/emsdk/emscripten/1.38.14/em++.bat")
set(CMAKE_CXX_COMPILER_ARG1 "")
set(CMAKE_CXX_COMPILER_ID "Clang")
set(CMAKE_CXX_COMPILER_VERSION "6.0.1")
set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "")
set(CMAKE_CXX_COMPILER_WRAPPER "")
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "98")
set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17")
set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters")
set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates")
set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates")
set(CMAKE_CXX17_COMPILE_FEATURES "")
set(CMAKE_CXX20_COMPILE_FEATURES "")

set(CMAKE_CXX_PLATFORM_ID "emscripten")
set(CMAKE_CXX_SIMULATE_ID "")
set(CMAKE_CXX_SIMULATE_VERSION "")



set(CMAKE_AR "C:/workspace/emsdk/emscripten/1.38.14/emar.bat")
set(CMAKE_CXX_COMPILER_AR "C:/Program Files/LLVM/bin/llvm-ar.exe")
set(CMAKE_RANLIB "C:/workspace/emsdk/emscripten/1.38.14/emranlib.bat")
set(CMAKE_CXX_COMPILER_RANLIB "C:/Program Files/LLVM/bin/llvm-ranlib.exe")
set(CMAKE_LINKER "C:/Program Files/LLVM/bin/wasm-ld.exe")
set(CMAKE_COMPILER_IS_GNUCXX )
set(CMAKE_CXX_COMPILER_LOADED 1)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_CXX_ABI_COMPILED )
set(CMAKE_COMPILER_IS_MINGW )
set(CMAKE_COMPILER_IS_CYGWIN )
if(CMAKE_COMPILER_IS_CYGWIN)
  set(CYGWIN 1)
  set(UNIX 1)
endif()

set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")

if(CMAKE_COMPILER_IS_MINGW)
  set(MINGW 1)
endif()
set(CMAKE_CXX_COMPILER_ID_RUN 1)
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;mm;CPP)
set(CMAKE_CXX_LINKER_PREFERENCE 30)
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)

# Save compiler ABI information.
set(CMAKE_CXX_SIZEOF_DATA_PTR "4")
set(CMAKE_CXX_COMPILER_ABI "")
set(CMAKE_CXX_LIBRARY_ARCHITECTURE "")

if(CMAKE_CXX_SIZEOF_DATA_PTR)
  set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
endif()

if(CMAKE_CXX_COMPILER_ABI)
  set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
endif()

if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
  set(CMAKE_LIBRARY_ARCHITECTURE "")
endif()

set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "")
if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
  set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
endif()





set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

最佳答案

终于找到问题了。命令生成的库;

emconfigure cmake.

即使我看到编译器使用 em++.bat 作为编译器,也不兼容 emcc。

如何发现问题。

我使用名为“Hex Editor Neo”的程序打开库文件(只使用小库文件进行测试,大库文件程序崩溃)。

如果不兼容emcc使用。前几个字符将是! arch 这行不通。 cmake生成错误的库文件见下图;

enter image description here

确保你有如下图所示的BC;

enter image description here

但是如何做到这一点

你不能只使用

emconfigure cmake .  <---------- wrong

您需要通过以下命令添加一个选项来生成位码(.bc)

emconfigure cmake . -DEMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES=1

然后会生成所有以.bc结尾的库文件,这些库文件可以用emcc链接

关于c++ - CMake 制作的 Emscripten 库无法链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55252435/

相关文章:

c++ - 使用/std :c++latest (or C++17/N4190) 使用 MSVC2015 编译 boost

c++ - 使用 C++ STL 中定义的堆栈

java - Mac 操作系统中的 Makefile "No rule to make target"错误

c++ - CMake 为 UWP 生成时无法获取 VCTargetsPath 的值

c++ - 如何为项目本身、构建产品和源文件创建一个具有不同位置的简单 CLion C++ CMake 项目

c++ - 可以使用 cmake 解决对符号的 undefined reference

c++ - 为什么必须将 SetWindowsHookEx 与 Windows 消息队列一起使用

c++ - gSOAP 动态数组作为输入参数

linux - 在 Makefile 中自定义 SHELL (set SHELL=my_shell.sh)

make 中的 Shell 状态代码