C++ CMake Qt项目中的链接和UIC顺序

C++ CMake Qt项目中的链接和UIC顺序,c++,qt,cmake,C++,Qt,Cmake,讨论使用cmake构建的Qt5.3.2项目。 这是UIC执行和目标链接库之间的调用顺序问题。。。不幸的是,顺序不是这样的 在这篇文章下面你会发现 1.)my CMakeLists.txt的(仍然有效)摘录部分,以及 2.)命令“cmake”输出的摘录 3.)不使用 生成的标题如“ui_main.h” 如果(在库libqt.a的源代码中)我需要'ui_main.h' 使进程崩溃,但找不到标头。看着 非崩溃生成输出显示了原因: [..] Scanning dependencies of target

讨论使用cmake构建的Qt5.3.2项目。 这是UIC执行和目标链接库之间的调用顺序问题。。。不幸的是,顺序不是这样的

在这篇文章下面你会发现

1.)my CMakeLists.txt的(仍然有效)摘录部分,以及

2.)命令“cmake”输出的摘录

3.)不使用 生成的标题如“ui_main.h”

如果(在库libqt.a的源代码中)我需要'ui_main.h' 使进程崩溃,但找不到标头。看着 非崩溃生成输出显示了原因:

[..]
Scanning dependencies of target qt
[ 29%] Building CXX object CMakeFiles/qt.dir/home/kochmn/projects/sentinel/src/qt/form_main.cpp.o
[ 35%] Building CXX object CMakeFiles/qt.dir/qt_automoc.cpp.o
Linking CXX static library libqt.a
[..]
[ 52%] Generating ui_main.h
[..]
Make将在生成所需的头文件之前生成libqt.a。 所以我尝试使用类似

target_link_libraries(sentinel
  ${Qt5Widgets_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Core_LIBRARIES})

add_library(optimization "${DIR_SRC}/optimization/linalg.cpp")
add_library(qt "${DIR_SRC}/qt/form_main.cpp")

target_link_libraries(sentinel qt optimization)
无济于事。问题是:如何激励cmake首先运行UIC生成ui头文件,然后编译libqt.a

附录 自动链接到qtmain.lib需要2.8.11而不是2.8 #库(如果有)应该扩展到Windows。 # (http://doc.qt.io/qt-5/cmake-manual.html) cmake_最低要求(版本2.8.11) 项目(哨兵) 设置(CMAKE_自动监控开启) #CMake使用uic从designer的.ui表单生成头文件。 设置(CMAKE AUTOUIC ON) #自动生成函数将其头写入生成目录。 #因此,应该包括构建目录。 设置(CMAKE\U INCLUDE\U CURRENT\U DIR ON) #>获取Qt基本要素---------------------------------------- #小部件找到自己的依赖项(QtGui和QtCore)。 查找_包(需要Qt5Widgets) 消息(“找到Qt5Widgets版本${Qt5Widgets\u版本\u字符串}”) #所有这些达令变量在此处解释: # http://doc.qt.io/qt-5/cmake-manual.html 消息(“找到的核心:${Qt5Core_FOUND}”) 消息(“Gui已找到:${Qt5Gui_已找到}”) 消息(“找到的小部件:${Qt5Widgets_FOUND}”) 消息(“核心版本:${Qt5Core_VERSION_STRING}”) 消息(“Gui版本:${Qt5Gui\U版本\U字符串}”) 消息(“小部件版本:${Qt5Widgets\u VERSION\u STRING}”) 消息(“核心包含:${Qt5Core\u包含\u目录}”) 消息(“Gui INCLUDE:${Qt5Gui\u INCLUDE\u DIRS}”) 消息(“小部件包含:${Qt5Widgets\u INCLUDE\u DIRS}”) 消息(“核心库:${Qt5Core_库}”) 消息(“Gui库:${Qt5Gui_库}”) 消息(“小部件库:${Qt5Widgets_库}”) 消息(“核心定义:${Qt5Core_定义}”) 消息(“Gui定义:${Qt5Gui_定义}”) 消息(“小部件定义:${Qt5Widgets_DEFINITIONS}”) 消息(“核心编译定义:${Qt5Core\u编译定义}”) 消息(“Gui编译定义:${Qt5Gui编译定义}”) 消息(“小部件编译定义:${Qt5Widgets编译定义}”) 消息(“核心可执行文件编译标志:${Qt5Core可执行文件编译标志}”) 消息(“Gui可执行文件编译标志:${Qt5Gui可执行文件编译标志}”) 消息(“小部件可执行文件编译标志:${Qt5Widgets可执行文件编译标志}”) 包含目录( ${Qt5Widgets_INCLUDE_DIRS}${Qt5Core_INCLUDE_DIRS}${Qt5Gui_INCLUDE_DIRS}) 添加_定义(${Qt5Widgets_定义}) #添加#u定义(${Qt5Core_定义})#不必要。在小部件中。 #添加#u定义(${Qt5Gui#u定义})#不必要。在小部件中。 #< ------------------------------------------------------------------- 设置(调试1) 设置(SENTINEL_名称“SENTINEL GL”) 设置(SENTINEL_版本_主要“0”) 设置(哨兵版本小调“1”) 设置(SENTINEL_VERSION“${SENTINEL_VERSION_MAJOR}.${SENTINEL_VERSION_MINOR}”) ##编译器标志 设置(CMAKE_CXX_标志“${CMAKE_CXX_标志}${Qt5Widgets_可执行文件_编译_标志}”) #${Qt5Core\u EXECUTABLE\u COMPILE\u FLAGS}${Qt5Gui\u EXECUTABLE\u COMPILE\u FLAGS}ui\u FormMain.h 设置(qt_H “${DIR\u BUILD}/ui\u main.h”“${DIR\u BUILD}/ui\u dialog\u setup\u game.h”) #使用可信的QtDesigner生成。 设置(qt_-UI) “${DIR\u SRC}/ui/main.ui”“${DIR\u SRC}/ui/dialog\u setup\u game.ui”) #我自己亲手编写的描述内部资源的XML。 set(qt_QRC“${DIR_RES}/application.QRC”) #生成用于生成moc生成的源文件的规则 QT5_WRAP_CPP(qt_H_MOC${qt_H}) #从ui文件生成用于构建头文件的规则 QT5_-WRAP_-UI(qt_-UI_-H${qt_-UI}) #资源处理。QRC:“Qt资源集合” QT5_添加_资源(qt_RCCS${qt_QRC}) #顺便说一句:rcc从./resources/application.qrc生成一个C程序 #然而,这是不必要的。cmake负责这一点。:-) #< ------------------------------------------------------------------- 包含目录(${DIR\u SRC}/包含“${PROJECT\u SOURCE\u DIR}”) 添加可执行文件(sentinel“${DIR\u SRC}/sentinel.cpp”${qt\u H\u MOC}${qt\u UI\u H}${qt\u RCCS}) #此处列出了可用的模块:http://doc.qt.io/qt-5/qtmodules.html #查找/usr/lib/x86_64-linux-gnu/cmake-iname“*.cmake*”less #注:http://stackoverflow.com/questions/20266235/cmake-error-qglwidget-no-such-file-or-directory qt5_使用_模块(sentinel Widgets Gui核心) 添加库(优化“${DIR\u SRC}/optimization/linalg.cpp”) 添加_库(qt“${DIR_SRC}/qt/form_main.cpp”) 目标链接库(sentinel ${Qt5Widgets_库}${Qt5Gui_库}${Qt5Core_库} qt优化 ) kochmn@Ulyss:~/projects/sentinel/build$cmake。 --C编译器标识为GNU4.9.2 --CXX编译器标识为GNU 4.9.2 --检查C编译器是否工作:/usr/bin/cc --检查C编译器是否工作:/usr/bin/cc--works --检测C编译器ABI信息 --检测C编译器ABI信息-完成 --检查CXX编译器是否工作:/usr/bin/c++ --检查CXX编译器是否正常工作:/usr/bin/c++--正常工作 --检测CXX编译器ABI信息 --检测CXX编译器ABI信息-完成 找到Qt5Widgets版本5.3.2 核心发现:1 Gui发现:1 找到的小部件:1 核心版本:5.3.2 Gui版本:5.3.2 小部件版本:5.3.2 核心包括:/usr/INCLUDE/x86_64-linux-gnu/qt5//usr/include/x86_64-linux-gnu/qt5/QtCore/usr/lib/x86_64-linux-gnu/qt5//mkspecs/linux-g++-64 Gui包含:/usr/INCLUDE/x86_64-linux-gnu/qt5
# 2.8.11 instead of 2.8 required for automatic linking to the qtmain.lib
# library if this ever should expand to Windows.
# (http://doc.qt.io/qt-5/cmake-manual.html)
cmake_minimum_required(VERSION 2.8.11)

project(sentinel)

set( CMAKE_AUTOMOC ON )
# CMake uses uic in order to generate header files from .ui forms from designer.
set ( CMAKE AUTOUIC ON )
# Auto-generating functions write their headers into the build directory.
# Hence the build directory should be included.
set( CMAKE_INCLUDE_CURRENT_DIR ON )

#> Getting the Qt essentials. ----------------------------------------
# Widgets finds its own dependencies (QtGui and QtCore).
find_package(Qt5Widgets REQUIRED)

message ("Found Qt5Widgets Version ${Qt5Widgets_VERSION_STRING}")

# All those darling variables are explained here:
# http://doc.qt.io/qt-5/cmake-manual.html
message("Core    FOUND: ${Qt5Core_FOUND}")
message("Gui     FOUND: ${Qt5Gui_FOUND}")
message("Widgets FOUND: ${Qt5Widgets_FOUND}")
message("Core    VERSION: ${Qt5Core_VERSION_STRING}")
message("Gui     VERSION: ${Qt5Gui_VERSION_STRING}")
message("Widgets VERSION: ${Qt5Widgets_VERSION_STRING}")
message("Core    INCLUDE: ${Qt5Core_INCLUDE_DIRS}")
message("Gui     INCLUDE: ${Qt5Gui_INCLUDE_DIRS}")
message("Widgets INCLUDE: ${Qt5Widgets_INCLUDE_DIRS}")
message("Core    LIBRARIES: ${Qt5Core_LIBRARIES}")
message("Gui     LIBRARIES: ${Qt5Gui_LIBRARIES}")
message("Widgets LIBRARIES: ${Qt5Widgets_LIBRARIES}")
message("Core    DEFINITIONS: ${Qt5Core_DEFINITIONS}")
message("Gui     DEFINITIONS: ${Qt5Gui_DEFINITIONS}")
message("Widgets DEFINITIONS: ${Qt5Widgets_DEFINITIONS}")
message("Core    COMPILE_DEFINITIONS: ${Qt5Core_COMPILE_DEFINITIONS}")
message("Gui     COMPILE_DEFINITIONS: ${Qt5Gui_COMPILE_DEFINITIONS}")
message("Widgets COMPILE_DEFINITIONS: ${Qt5Widgets_COMPILE_DEFINITIONS}")
message("Core    EXECUTABLE_COMPILE_FLAGS: ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
message("Gui     EXECUTABLE_COMPILE_FLAGS: ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS}")
message("Widgets EXECUTABLE_COMPILE_FLAGS: ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")

include_directories(
  ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS})

add_definitions(${Qt5Widgets_DEFINITIONS})
#add_definitions(${Qt5Core_DEFINITIONS}) # Unnecessary. In Widgets.
#add_definitions(${Qt5Gui_DEFINITIONS})  # Unnecessary. In Widgets.
#< -------------------------------------------------------------------

set (DEBUG 1)
set (SENTINEL_NAME "Sentinel GL")
set (SENTINEL_VERSION_MAJOR "0")
set (SENTINEL_VERSION_MINOR "1")
set (SENTINEL_VERSION "${SENTINEL_VERSION_MAJOR}.${SENTINEL_VERSION_MINOR}")

## Compiler flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
#  ${Qt5Core_EXECUTABLE_COMPILE_FLAGS} ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS} #<-- redundant.

if(CMAKE_COMPILER_IS_GNUCXX)
  message("Using GnuCXX compiler.")
  add_definitions("-O0 -std=c++0x -lSOIL -llapacke -lblas")
endif()

if (DEBUG MATCHES 1)
  message("\nBuilding DEBUG build.")
  add_definitions(-Wall)
  set(CMAKE_BUILD_TYPE Debug)
endif()

set(DIR_BASE "${PROJECT_SOURCE_DIR}/..")
set(DIR_SRC "${PROJECT_SOURCE_DIR}/../src")
set(DIR_RES "${PROJECT_SOURCE_DIR}/../resources")
set(DIR_BUILD "${PROJECT_SOURCE_DIR}/../build")

# Generated using uic FormMain.ui > ui_FormMain.h
set(qt_H
  "${DIR_BUILD}/ui_main.h" "${DIR_BUILD}/ui_dialog_setup_game.h")
# Generated using the trusty QtDesigner.
set(qt_UI
  "${DIR_SRC}/ui/main.ui" "${DIR_SRC}/ui/dialog_setup_game.ui")
# My own hand-written XML describing the internal resources.
set(qt_QRC "${DIR_RES}/application.qrc")

# generate rules for building source files that moc generates
QT5_WRAP_CPP(qt_H_MOC ${qt_H})
# generate rules for building header files from the ui files
QT5_WRAP_UI(qt_UI_H ${qt_UI})
# Resource Handling. QRC: "Qt Resource Collection"
QT5_ADD_RESOURCES(qt_RCCS ${qt_QRC})
# btw.: rcc generates a C program from ./resources/application.qrc
# However, this is not needed. cmake sees to that. :-)
#< -------------------------------------------------------------------

include_directories("${DIR_SRC}/include" "${PROJECT_SOURCE_DIR}")

add_executable(sentinel "${DIR_SRC}/sentinel.cpp" ${qt_H_MOC} ${qt_UI_H} ${qt_RCCS})

# Available modules are listed here: http://doc.qt.io/qt-5/qtmodules.html
#   find /usr/lib/x86_64-linux-gnu/cmake -iname "*.cmake*" | less
# Note: http://stackoverflow.com/questions/20266235/cmake-error-qglwidget-no-such-file-or-directory
qt5_use_modules(sentinel Widgets Gui Core)

add_library(optimization "${DIR_SRC}/optimization/linalg.cpp")
add_library(qt "${DIR_SRC}/qt/form_main.cpp")

target_link_libraries(sentinel
  ${Qt5Widgets_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Core_LIBRARIES}
  qt optimization
)

kochmn@Ulyss:~/projects/sentinel/build$ cmake .
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
Found Qt5Widgets Version 5.3.2
Core    FOUND: 1
Gui     FOUND: 1
Widgets FOUND: 1
Core    VERSION: 5.3.2
Gui     VERSION: 5.3.2
Widgets VERSION: 5.3.2
Core    INCLUDE: /usr/include/x86_64-linux-gnu/qt5/;/usr/include/x86_64-linux-gnu/qt5/QtCore;/usr/lib/x86_64-linux-gnu/qt5//mkspecs/linux-g++-64
Gui     INCLUDE: /usr/include/x86_64-linux-gnu/qt5/;/usr/include/x86_64-linux-gnu/qt5/QtGui;/usr/include/x86_64-linux-gnu/qt5/QtCore;/usr/lib/x86_64-linux-gnu/qt5//mkspecs/linux-g++-64
Widgets INCLUDE: /usr/include/x86_64-linux-gnu/qt5/;/usr/include/x86_64-linux-gnu/qt5/QtWidgets;/usr/include/x86_64-linux-gnu/qt5/QtGui;/usr/include/x86_64-linux-gnu/qt5/QtCore;/usr/lib/x86_64-linux-gnu/qt5//mkspecs/linux-g++-64
Core    LIBRARIES: Qt5::Core
Gui     LIBRARIES: Qt5::Gui
Widgets LIBRARIES: Qt5::Widgets
Core    DEFINITIONS: -DQT_CORE_LIB
Gui     DEFINITIONS: -DQT_GUI_LIB;-DQT_CORE_LIB
Widgets DEFINITIONS: -DQT_WIDGETS_LIB;-DQT_GUI_LIB;-DQT_CORE_LIB
Core    COMPILE_DEFINITIONS: QT_CORE_LIB
Gui     COMPILE_DEFINITIONS: QT_GUI_LIB;QT_CORE_LIB
Widgets COMPILE_DEFINITIONS: QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB
Core    EXECUTABLE_COMPILE_FLAGS: -fPIE
Gui     EXECUTABLE_COMPILE_FLAGS: -fPIE
Widgets EXECUTABLE_COMPILE_FLAGS: -fPIE
Using GnuCXX compiler.

Building DEBUG build.

Sentinel GL -- C++ Project V 0.1.

(c) Markus-Hermann Koch, mhk@markuskoch.eu, 2015/04/28-?

Primary directory is /home/kochmn/projects/sentinel/build
System is Linux
Generating configuration header: "/home/kochmn/projects/sentinel/build/../build/mhk_cmake_config.h"
-- Configuring done
-- Generating done
-- Build files have been written to: /home/kochmn/projects/sentinel/build

kochmn@Ulyss:~/projects/sentinel/build$ make 
Scanning dependencies of target optimization_automoc
[  5%] Automatic moc for target optimization
[  5%] Built target optimization_automoc
Scanning dependencies of target optimization
[ 11%] Building CXX object CMakeFiles/optimization.dir/home/kochmn/projects/sentinel/src/optimization/linalg.cpp.o
[ 17%] Building CXX object CMakeFiles/optimization.dir/optimization_automoc.cpp.o
Linking CXX static library liboptimization.a
[ 17%] Built target optimization
Scanning dependencies of target qt_automoc
[ 23%] Automatic moc for target qt
[ 23%] Built target qt_automoc
Scanning dependencies of target qt
[ 29%] Building CXX object CMakeFiles/qt.dir/home/kochmn/projects/sentinel/src/qt/form_main.cpp.o
[ 35%] Building CXX object CMakeFiles/qt.dir/qt_automoc.cpp.o
Linking CXX static library libqt.a
[ 35%] Built target qt
Scanning dependencies of target sentinel_automoc
[ 41%] Automatic moc for target sentinel
[ 41%] Built target sentinel_automoc
[ 47%] Generating qrc_application.cpp
[ 52%] Generating ui_main.h
[ 58%] Generating moc_ui_main.cpp
/home/kochmn/projects/sentinel/build/ui_main.h:0: Note: No relevant classes found. No output generated.
[ 64%] Generating ui_dialog_setup_game.h
[ 70%] Generating moc_ui_dialog_setup_game.cpp
/home/kochmn/projects/sentinel/build/ui_dialog_setup_game.h:0: Note: No relevant classes found. No output generated.
Scanning dependencies of target sentinel
[ 76%] Building CXX object CMakeFiles/sentinel.dir/home/kochmn/projects/sentinel/src/sentinel.cpp.o
[ 82%] Building CXX object CMakeFiles/sentinel.dir/moc_ui_main.cpp.o
[ 88%] Building CXX object CMakeFiles/sentinel.dir/moc_ui_dialog_setup_game.cpp.o
[ 94%] Building CXX object CMakeFiles/sentinel.dir/qrc_application.cpp.o
[100%] Building CXX object CMakeFiles/sentinel.dir/sentinel_automoc.cpp.o
Linking CXX executable sentinel
[100%] Built target sentinel
QT5_WRAP_UI(qt_UI_H ${qt_UI})
[...]
add_library(qt "${DIR_SRC}/qt/form_main.cpp" ${qt_UI_H})