CMake Qt 项目中的链接和 UIC 顺序
Linking and UIC order in a CMake Qt project
谈论一个使用 cmake 构建的 Qt 5.3.2 项目。
这是 UIC 执行和 target_link_libraries 之间的调用顺序问题...不幸的是 不是 这个顺序。
在这段文字下方你会发现
1.) 我的 CMakeLists.txt 和
的(仍然有效的)摘录部分
2.) 命令输出的摘录 'cmake .'
3.) 在不使用
生成了 header 类似 'ui_main.h'.
如果(在我的库 libqt.a 中)我需要 'ui_main.h'
make 进程因找不到 header 而崩溃。看着
non-crashing 使输出显示原因:
[..]
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 会在 生成所需的 header 文件之前生成 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 first 运行 UIC 生成 ui-header 文件并 then 编译我的 libqt.a?
附录
# 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:
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
CMake 生成顺序是根据文件和目标之间的依赖关系计算的。如果您的 qt 库依赖于从 .ui 文件生成的 headers,那么您必须在目标 qt
的输入中添加 ${qt_UI_H}
:
QT5_WRAP_UI(qt_UI_H ${qt_UI})
[...]
add_library(qt "${DIR_SRC}/qt/form_main.cpp" ${qt_UI_H})
并且 CMake 通常应该在编译之前对 .ui 文件执行 UIC libqt
顺便说一下,使用 target_link_libraries
仅在 link 时间 设置目标之间的依赖关系。在编译时,正常行为是 "All source files should be found"。在您的情况下,生成了一些 headers,因此将这些 headers 设置为目标的输入可确保生成它们的宏 (QT5_WRAP_UI) 将在编译目标之前执行。
谈论一个使用 cmake 构建的 Qt 5.3.2 项目。 这是 UIC 执行和 target_link_libraries 之间的调用顺序问题...不幸的是 不是 这个顺序。
在这段文字下方你会发现
1.) 我的 CMakeLists.txt 和
的(仍然有效的)摘录部分2.) 命令输出的摘录 'cmake .'
3.) 在不使用 生成了 header 类似 'ui_main.h'.
如果(在我的库 libqt.a 中)我需要 'ui_main.h' make 进程因找不到 header 而崩溃。看着 non-crashing 使输出显示原因:
[..]
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 会在 生成所需的 header 文件之前生成 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 first 运行 UIC 生成 ui-header 文件并 then 编译我的 libqt.a?
附录
# 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:
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
CMake 生成顺序是根据文件和目标之间的依赖关系计算的。如果您的 qt 库依赖于从 .ui 文件生成的 headers,那么您必须在目标 qt
的输入中添加 ${qt_UI_H}
:
QT5_WRAP_UI(qt_UI_H ${qt_UI})
[...]
add_library(qt "${DIR_SRC}/qt/form_main.cpp" ${qt_UI_H})
并且 CMake 通常应该在编译之前对 .ui 文件执行 UIC libqt
顺便说一下,使用 target_link_libraries
仅在 link 时间 设置目标之间的依赖关系。在编译时,正常行为是 "All source files should be found"。在您的情况下,生成了一些 headers,因此将这些 headers 设置为目标的输入可确保生成它们的宏 (QT5_WRAP_UI) 将在编译目标之前执行。