即使库已链接,CMake 可执行链接器错误
CMake executable linker error even though the libraries are linked
我是 CMake 的新手,但我已经遇到了一个我不明白的错误。
出于给定的原因,我有以下 C++ 设置:我有两个自己的静态库、多个外部静态库和一个可执行文件。我自己的库 a
定义了通用内容,所有外部库都被 link 编入其中。我的图书馆 b
定义了更多特殊的东西,并且有图书馆 a
link 编入其中。最后,b
被 link 编辑到我的可执行文件 c
中。 b
和c
都使用了不同外部库的函数,应该可以通过a
.
看到
我有以下 CMakeLists.txt,我通过仅使用一个外部库来减少问题:ZeroC Ice。
根目录CMakeLists.txt
cmake_minimum_required (VERSION 3.3.0)
project (myproject)
# some settings
if (CMAKE_COMPILER_IS_GNUCC)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
endif (CMAKE_COMPILER_IS_GNUCC)
if (CMAKE_COMPILER_IS_GNUCXX)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmessage-length=0")
endif (CMAKE_COMPILER_IS_GNUCXX)
set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols")
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
# ZeroC Ice
find_package (Ice 3.6.0 REQUIRED COMPONENTS Ice IceUtil)
include_directories (${Ice_INCLUDE_DIRS})
# libraries and executable
add_subdirectory (a)
add_subdirectory (b)
add_subdirectory (c)
CMakeLists.txt 对于 a
set (a_FILES
stuff.cpp
)
add_library (a STATIC ${a_FILES})
# link to third-party libraries
target_link_libraries (a PUBLIC
${Ice_LIBRARIES}
)
CMakeLists.txt 对于 b
set (b_FILES
more_stuff.cpp
)
add_library (b STATIC ${b_FILES})
# link to a
target_link_libraries (b PUBLIC
a
)
CMakeLists.txt 对于 c
set (c_FILES
main.cpp
)
add_executable (c ${c_FILES})
# link to b
target_link_libraries (c PUBLIC
b
)
在此示例中,stuff.cpp
、more_stuff.cpp
和 main.cpp
使用 Ice 库中的 类。 a
甚至 b
编译和 link 都没有任何问题。只有 c
会抛出很多类似的 linker 错误:
C:/PROGRA~2/ZeroC/ICE-36~1.0/include/Ice/FactoryTableInit.h:27: undefined reference to `_imp___ZN11IceInternal16FactoryTableInitD1Ev'
对我来说,CMakeLists.txt 设置看起来很好,用谷歌搜索了好几天也没有任何改变。如果有任何帮助,我将不胜感激!
我正在使用 CMake 3.3.1 和 CMake Generator "Eclipse CDT4 - MinGW Makefiles"(g++ 版本 4.8.1)开发 Windows 10。
提前致谢! :)
编辑:
c
的 g++ linker 输出显示它试图 link 反对 liba.a libb.a C:/.../ice.lib C:/.../iceutil.lib
,这对我来说似乎很好。无论如何,undefined reference
linker 错误发生在 类 在 ice.lib
内部实现的头文件中,所以我不知道这里出了什么问题...
a
和 b
是静态库,它们只是带有用于外部引用的符号的归档对象,没有 linking 发生。 c
是最终解析这些符号和 link 依赖关系的可执行文件。它看起来不像 CMake 向上传输 Ice 库 link,你可以尝试只 link 她的可执行文件。
我自己找到了一个"workaround":使用另一个CMake生成器。通过使用 Visual Studio 作为底层编译器和链接器,问题不会出现。问题似乎是混淆了 .lib
和 .a
库。由于 windows 上的默认 Ice 安装仅提供 .lib
文件,我最终切换到 VS,一切正常。
我是 CMake 的新手,但我已经遇到了一个我不明白的错误。
出于给定的原因,我有以下 C++ 设置:我有两个自己的静态库、多个外部静态库和一个可执行文件。我自己的库 a
定义了通用内容,所有外部库都被 link 编入其中。我的图书馆 b
定义了更多特殊的东西,并且有图书馆 a
link 编入其中。最后,b
被 link 编辑到我的可执行文件 c
中。 b
和c
都使用了不同外部库的函数,应该可以通过a
.
我有以下 CMakeLists.txt,我通过仅使用一个外部库来减少问题:ZeroC Ice。
根目录CMakeLists.txt
cmake_minimum_required (VERSION 3.3.0)
project (myproject)
# some settings
if (CMAKE_COMPILER_IS_GNUCC)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
endif (CMAKE_COMPILER_IS_GNUCC)
if (CMAKE_COMPILER_IS_GNUCXX)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmessage-length=0")
endif (CMAKE_COMPILER_IS_GNUCXX)
set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols")
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
# ZeroC Ice
find_package (Ice 3.6.0 REQUIRED COMPONENTS Ice IceUtil)
include_directories (${Ice_INCLUDE_DIRS})
# libraries and executable
add_subdirectory (a)
add_subdirectory (b)
add_subdirectory (c)
CMakeLists.txt 对于 a
set (a_FILES
stuff.cpp
)
add_library (a STATIC ${a_FILES})
# link to third-party libraries
target_link_libraries (a PUBLIC
${Ice_LIBRARIES}
)
CMakeLists.txt 对于 b
set (b_FILES
more_stuff.cpp
)
add_library (b STATIC ${b_FILES})
# link to a
target_link_libraries (b PUBLIC
a
)
CMakeLists.txt 对于 c
set (c_FILES
main.cpp
)
add_executable (c ${c_FILES})
# link to b
target_link_libraries (c PUBLIC
b
)
在此示例中,stuff.cpp
、more_stuff.cpp
和 main.cpp
使用 Ice 库中的 类。 a
甚至 b
编译和 link 都没有任何问题。只有 c
会抛出很多类似的 linker 错误:
C:/PROGRA~2/ZeroC/ICE-36~1.0/include/Ice/FactoryTableInit.h:27: undefined reference to `_imp___ZN11IceInternal16FactoryTableInitD1Ev'
对我来说,CMakeLists.txt 设置看起来很好,用谷歌搜索了好几天也没有任何改变。如果有任何帮助,我将不胜感激!
我正在使用 CMake 3.3.1 和 CMake Generator "Eclipse CDT4 - MinGW Makefiles"(g++ 版本 4.8.1)开发 Windows 10。
提前致谢! :)
编辑:
c
的 g++ linker 输出显示它试图 link 反对 liba.a libb.a C:/.../ice.lib C:/.../iceutil.lib
,这对我来说似乎很好。无论如何,undefined reference
linker 错误发生在 类 在 ice.lib
内部实现的头文件中,所以我不知道这里出了什么问题...
a
和 b
是静态库,它们只是带有用于外部引用的符号的归档对象,没有 linking 发生。 c
是最终解析这些符号和 link 依赖关系的可执行文件。它看起来不像 CMake 向上传输 Ice 库 link,你可以尝试只 link 她的可执行文件。
我自己找到了一个"workaround":使用另一个CMake生成器。通过使用 Visual Studio 作为底层编译器和链接器,问题不会出现。问题似乎是混淆了 .lib
和 .a
库。由于 windows 上的默认 Ice 安装仅提供 .lib
文件,我最终切换到 VS,一切正常。