Qt的5.0版本带来了一组更简单的命令来使用CMake构建Qt项目。见 http://qt-project.org/doc/qt-5/cmake-manual.html.需要使用命令包含项目的资源 QT5_ADD_资源.

如果我的资源文件以实例Icon32命名。qrc, QT5_ADD_RESOURCES(资源Icon32。qrc) 命令会自动将其转换为 qrc_Icon32.cpp 文件并定义一个 ${资源} 变量,然后我将能够包括到适当的目标。

这样做是完美的, 除了我在CDash中得到一个编译错误大约每20个构建一次.该错误通常为以下形式:

/.../CMake/build/qrc_Icon32.cpp:272380:1: error: unknown type name 'qCleanupResources_Icon32'

正在发生的事情是,最后一行的可变部分 qrc_Icon32.cpp 文件在文件结束后重复,从而为编译器创建最后一行无意义的行。

记录CMake所做的事情,似乎是 QT5_ADD_资源 以下是:每当它到达一个需要相关资源的项目时,它就会执行一个 依赖 创建特定于编译目标的文件,但仍然会写入 qrc_Icon32.cpp 在构建目录的根目录, ,而这对于所有目标。因此,如果两个目标并行编译,则两个调用 rcc 可能在同一时间写入同一个文件,因此损坏。

我还没有在网络上找到任何关于这个问题/功能的报告/讨论,所以我想知道我是否可能错过了一些东西:

有没有办法告诉CMake保存生成的 qrc_Icon32.cpp 每个目标在不同的位置?更好的是,是否有可能告诉CMake打电话 rcc 只有一次从它的主make文件,以便 qrc_Icon32.cpp 以后是否可用于所有目标?

我想一个解决方法是创建一个静态库,这将是唯一一个使用 ${资源} 然后将该库链接到所有目标。但是,我认为CMake应该能够在使用多线程-j标志编译时正确管理其依赖关系。


若要重现此问题,请在空文件夹中创建CMakeList。包含以下内容的txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11)
PROJECT(SSCCE CXX)

set(CMAKE_PREFIX_PATH /usr/local/Qt-5.3.0 ${CMAKE_PREFIX_PATH})

set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

INCLUDE_DIRECTORIES(SYSTEM "/usr/local/Qt-5.3.0/include/QtCore")
find_package(Qt5Core REQUIRED)
QT5_ADD_RESOURCES(RESOURCES Icon32.qrc)

SET(LIBLIST gobject-2.0 X11-xcb Xi xcb-render-util SM ICE xcb-glx xcb-render xcb-atom xcb-property xcb-event dbus-1 xcb xcb-image xcb-icccm xcb-sync xcb-xfixes xcb-shm xcb-randr xcb-shape xcb-keysyms fontconfig freetype Xrender Xext X11 jpeg png Qt5::Core z m dl gthread-2.0 rt glib-2.0 GL pthread)

ADD_EXECUTABLE(FirstTarget Main1.cpp ${RESOURCES})
TARGET_LINK_LIBRARIES(FirstTarget ${LIBLIST})
ADD_EXECUTABLE(SecondTarget Main2.cpp ${RESOURCES})
TARGET_LINK_LIBRARIES(SecondTarget ${LIBLIST})

然后Main1。cpp和Main2。cpp是使用

#include <iostream>

using namespace std;

int main(int argc, char** argv) {
        std::cout<<"Hello World 1"<<std::endl;
        return 0;
}

Qrc文件是

<RCC>
    <qresource prefix="/">
        <file>Icon32/YourImage.png</file>
    </qresource>
</RCC>

然后创建一个名为Icon32的文件夹,并添加您选择的名称yourimage的png图像。巴布亚新几内亚。

最后,创建一个构建目录,进入它并运行:

cmake -DCMAKE_CXX_COMPILER=g++-4.8 -DCMAKE_CXX_FLAGS='-std=c++11 -fPIE' ..
make -j2

输出应该是这样的

Scanning dependencies of target FirstTarget_automoc
Scanning dependencies of target SecondTarget_automoc
[ 10%] [ 20%] Automoc for target FirstTarget
Automoc for target SecondTarget
[ 20%] [ 20%] Built target FirstTarget_automoc
Built target SecondTarget_automoc
[ 30%] [ 40%] Generating qrc_Icon32.cpp
Generating qrc_Icon32.cpp
Scanning dependencies of target SecondTarget
Scanning dependencies of target FirstTarget
[ 50%] [ 60%] Building CXX object CMakeFiles/SecondTarget.dir/Main2.cpp.o
Building CXX object CMakeFiles/FirstTarget.dir/Main1.cpp.o
[ 70%] [ 80%] Building CXX object CMakeFiles/SecondTarget.dir/qrc_Icon32.cpp.o
Building CXX object CMakeFiles/FirstTarget.dir/qrc_Icon32.cpp.o
[ 90%] [100%] Building CXX object CMakeFiles/SecondTarget.dir /SecondTarget_automoc.cpp.o
Building CXX object CMakeFiles/FirstTarget.dir/FirstTarget_automoc.cpp.o
Linking CXX executable SecondTarget
Linking CXX executable FirstTarget

可以看到qrc_Icon32。cpp大约在同一时间在生成目录的根目录创建两次。的qrc_Icon32。cpp。o文件虽然在FirstTarget中正确创建。dir和SecondTarget。dir所以没有冲突。

我的意思是:1)qrc_Icon32.cpp应该在FirstTarget中创建。dir和SecondTarget。dir以及或 2)它应该在构建目录的根目录中创建,但对于所有目标只能创建一次。

有帮助吗?

解决方案

qt5_add_resources将文件写入 CMAKE_CURRENT_BINARY_DIR, ,不 CMAKE_BINARY_DIR

https://qt.gitorious.org/qt/qtbase/source/d953d9a4c3bdc5ed3b8d380c4b893b51b523bc50:src/corelib/Qt5CoreMacros.cmake#L205

同上Qt4:

http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/Qt4Macros.cmake;h=b1b12d68b07aac076719c681fb844f4f98ba8151;hb=HEAD#l212

更新资料:

使用您在更新中提供的源代码,可以看到问题。

http://www.cmake.org/pipermail/cmake/2008-October/024492.html

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0ece8f79

http://public.kitware.com/Bug/view.php?id=12311

解决方法是添加自定义目标,并根据该目标添加显式目标。

cmake_minimum_required(VERSION 2.8.11)

project(MyTest)

find_package(Qt5Core)

qt5_add_resources(RSCS somefile.qrc)
add_custom_target(gen_qrc DEPENDS ${RSCS})

add_executable(foo foo.cpp ${RSCS})
add_dependencies(foo gen_qrc)
add_executable(bar bar.cpp ${RSCS})
add_dependencies(bar gen_qrc)

CMake3.0具有AUTORCC功能:

http://www.cmake.org/cmake/help/v3.0/manual/cmake-qt.7.html#autorcc

它还将生成的qrc_文件放在当前构建目录中。CMake3.1将把它放在特定于目标的目录中,使这个问题消失:

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=33774ca2

其他提示

报告的行为是由于在过程中提前调用 qt5_add_resources ,在配置期间和编译之前开始。此时,史蒂维尔指出的变量 $ {cmake_current_binary_dir} 被定义为 root build文件夹。 (这可以通过添加消息( qt5coremacros.cake 中的消息(输出来轻松测试。

函数 qt5_add_resources 是创建在编译过程中调用的自定义命令: https://qt.gitorious.org/qt / qtbase/source/d953d9a4c3bdc5ed3b8d380c4b893b51b523bc50%3aSrc/corelib/qt5coremacros.cmake#l231

如果定义了多个目标,那么稍后可以同时调用这些自定义命令。在那一刻, $ {outfile} 将不会使用当时 $ {cmake_current_binary_dir} ,因此并行进程将在同一文件中写入同一文件构建目录。

查看 qt5_add_resources 没有机制/选项似乎可以在多线程编译情况下纠正该行为,但是,如史蒂夫雷所指出的,底层自定义命令函数的解决方法也可以成功应用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top