使用cmake交叉编译qt应用程序时的链接问题
Linking problem when trying to cross-compile a qt application using cmake
我目前正在切换我的Qt应用程序的构建系统从qmake到cmake。在尝试用MinGW(静态Qt构建)交叉编译Windows时,我遇到了一个我无法解释的奇怪问题:
CMakeLists.txt:
project(noble)
cmake_minimum_required(VERSION 2.8.5)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
find_package(Boost COMPONENTS program_options thread REQUIRED)
find_package(Qt4 REQUIRED QtCore QtGui)
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
find_package(Armadillo)
find_package(Qwt6 REQUIRED)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
include(${QT_USE_FILE})
set(LIBRARIES
${Qwt6_Qt4_LIBRARY}
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${Boost_LIBRARIES}
${BLAS_LIBRARIES}
${LAPACK_LIBRARIES}
)
set(DEFINITIONS
${QT_DEFINITIONS}
${BLAS_LINKER_FLAGS}
${LAPACK_LINKER_FLAGS}
-DBOOST_THREAD_USE_LIB
)
add_subdirectory(src)
add_subdirectory(plugins)
src/CMakeLists.txt:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(noble_SOURCES
#file names...
)
set(noble_HEADERS
#file names...
)
set(noble_FORMS
#file names...
)
QT4_WRAP_UI(noble_FORMS_HEADERS ${noble_FORMS})
QT4_WRAP_CPP(noble_HEADERS_MOC ${noble_HEADERS})
include_directories(
${Boost_INCLUDE_DIRS}
${ARMADILLO_INCLUDE_DIRS}
${Qwt6_INCLUDE_DIR}
)
add_definitions(${DEFINITIONS})
add_executable(noble
${noble_SOURCES}
${noble_HEADERS_MOC}
${noble_FORMS_HEADERS}
)
target_link_libraries(noble
${LIBRARIES}
-lQtGui -lQtCore
-ljpeg -lpng -ltiff -lmng -lz -limm32 -llcms -lwinmm
-fopenmp
)
我现在试图摆脱手动设置编译器标志的权利在最后。如果省略-lQtGui -lQtCore
,就会得到一堆未定义引用,比如
/home/mjung/Programme/mingw-cross-env-2.21/usr/lib/gcc/i686-pc-mingw32/4.6.0/../../../../i686-pc-mingw32/lib/libQtGui.a(qapplication.o):qapplication.cpp:(.text+0x2340): undefined reference to `QBasicTimer::stop()'
如果我保留这些标志,程序可以正常编译。
现在奇怪的事情是:
cmake g++叫与 -lQtGui -lQtCore
标记:
/home/mjung/Programme/mingw-cross-env-2.21/usr/bin/i686-pc-mingw32-g++
-Wl,--whole-archive
CMakeFiles/noble.dir/objects.a
-Wl,--no-whole-archive
-o ../noble.exe
-Wl,--out-implib,../libnoble.dll.a
-Wl,--major-image-version,0,--minor-image-version,0
/home/mjung/Programme/windows_builds/usr/lib/libqwt.a
-Wl,-Bstatic
-lQtCore -lQtGui
-lboost_program_options-mt
-lboost_thread-mt
-Wl,-Bdynamic
/home/mjung/Programme/windows_builds/usr/lib/libblas.a
/home/mjung/Programme/windows_builds/usr/lib/liblapack.a
/home/mjung/Programme/windows_builds/usr/lib/libblas.a
-lQtGui -lQtCore
-ljpeg -lpng -ltiff -lmng -lz -limm32 -llcms -lwinmm
-fopenmp
/home/mjung/Programme/windows_builds/usr/lib/liblapack.a
-lQtGui -lQtCore
-ljpeg -lpng -ltiff -lmng -lz -limm32 -llcms -lwinmm
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
cmake的g++调用没有 -lQtGui -lQtCore
标志:
/home/mjung/Programme/mingw-cross-env-2.21/usr/bin/i686-pc-mingw32-g++
-Wl,--whole-archive
CMakeFiles/noble.dir/objects.a
-Wl,--no-whole-archive
-o ../noble.exe
-Wl,--out-implib,../libnoble.dll.a
-Wl,--major-image-version,0,--minor-image-version,0
/home/mjung/Programme/windows_builds/usr/lib/libqwt.a
-Wl,-Bstatic
-lQtCore -lQtGui
-lboost_program_options-mt
-lboost_thread-mt
-Wl,-Bdynamic
/home/mjung/Programme/windows_builds/usr/lib/libblas.a
/home/mjung/Programme/windows_builds/usr/lib/liblapack.a
/home/mjung/Programme/windows_builds/usr/lib/libblas.a
-ljpeg -lpng -ltiff -lmng -lz -limm32 -llcms -lwinmm
-fopenmp
/home/mjung/Programme/windows_builds/usr/lib/liblapack.a
-ljpeg -lpng -ltiff -lmng -lz -limm32 -llcms -lwinmm
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
即使我做不是手动设置编译器标志,FindQt4.cmake
脚本仍然设置它们。但这似乎还不够。我完全不明白,如果自动设置一次标志,或者手动添加三次标志,为什么会有什么不同。这和旗帜的顺序有关吗?
你有什么想法吗?如有任何帮助,不胜感激。
更新:
别介意……我只是从
改变了库的顺序set(LIBRARIES
${Qwt6_Qt4_LIBRARY}
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${Boost_LIBRARIES}
${BLAS_LIBRARIES}
${LAPACK_LIBRARIES}
)
set(LIBRARIES
${Qwt6_Qt4_LIBRARY}
${QT_QTGUI_LIBRARY}
${QT_QTCORE_LIBRARY}
${Boost_LIBRARIES}
${BLAS_LIBRARIES}
${LAPACK_LIBRARIES}
)
我不太明白为什么要这样,但现在它工作了…
PS:我本来想把这个贴出来作为一个答案,但由于缺乏声誉,我还不允许这样做。
许多体系结构在链接时只遍历库列表。也就是说,如果你有一个未定义的符号,链接列表中后面的库必须定义它。链接器不会"向后"搜索库列表来解析该符号。
在这种情况下,QtGui依赖于QtCore。因此,QtCore必须出现在链接列表中的QtGui之后。
最简单的方法是使用${QT_LIBRARIES} cmake变量,该变量在执行FIND_PACKAGE(Qt4…)时神奇地定义。它有所有相关的Qt库在正确的顺序为链接。
FindQt4 CMake文档
相关文章:
- 使用jsoncpp库时出现链接问题
- Cmake 链接问题:未定义对 Button::mousePressEvent(QGraphicsSceneMouseE
- 如何将GTest与CMake一起使用?遵循谷歌指南时的链接问题
- 未解决的外部链接问题
- 'make check' GLIBC 运行时的链接问题
- 在树莓派上用libtorch构建程序时的链接问题
- 野牛弹性链接问题
- 与 AWS 开发工具包的链接问题
- Qt & Firebase C++ SDK 在 iOS 上的链接问题
- 链接问题 boost::p ython::numpy.
- 与 32 位共享对象的链接问题
- 在单元测试项目中包括 .c 文件,并从多个 cpp 文件访问它而不会出现链接问题
- 安卓链接问题
- LLVM 传递链接问题:未定义的符号
- Cmake Mac OSX库链接问题:在Linux上进行编译,但在Mac上进行了编译
- 用libclang解析源文件 - 链接问题包括文件
- C / C++链接问题与非常简单的设置
- Zbar 在 vs2015 链接问题
- Vulkan + GLFW + Cmake在Linux环境下的链接问题
- TFS构建由于链接问题而失败