Resource danneggiato file .CPP quando si utilizza QT5_ADD_RESOURCES e compilazione multithread con cmake

StackOverflow https://stackoverflow.com//questions/23041356

Domanda

La versione 5.0 di QT ha portato un set di comandi più semplici per creare progetti Qt usando cmake. Vedi http://qt-project.org/doc/qt-5/ cmake-manual.html . Le risorse per un progetto devono essere incluse utilizzando il comando qt5_add_resources .

Se il mio file di risorsa è denominato per esempio ICON32.QRC, QT5_ADD_RESOURCES (RISORSE ICON32.QRC) Comando lo convertirà automaticamente in un file QRC_ICON32.CPP e definire A $ {Risorse} Variabile che sarò in grado di includere nei bersagli corretti.

Fare questo funziona perfettamente, tranne che ricevo un errore di compilazione in cososh approssimativamente una volta ogni 20 build . L'errore è in genere del seguente modulo:

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

Cosa sta succedendo è che una parte variabile dell'ultima riga del file QRC_ICON32.CPP viene ripetuta dopo quanto dovrebbe normalmente la fine del file, creando così un'ultima linea nonnsicsica per il compilatore. < / P >.

Registrazione Che cmake lo fa, sembra che il comportamento di qt5_add_resources sia il seguente: ogni volta che raggiunge un progetto che richiede le risorse in questione, esegue un dipende da File che è specifico per l'obiettivo di compilazione ma che avrebbe ancora scritto il qrc_icon32.cpp nella root della directory di build , e questo per tutti i bersagli. Quindi se due bersagli vengono compilati in parallelo, due invocazioni di RCC potrebbero scriverti nello stesso file contemporaneamente, quindi la corruzione.

Non ho trovato alcun rapporto / discussione di questo problema / funzione sul web quindi mi chiedo se avrei potuto perdere qualcosa:

C'è un modo per dire a cmake di salvare il QRC_ICON32.CPP generato in una posizione diversa per ogni target? Meglio ancora, è possibile dire a Cmake a chiamare RCC solo una volta dal suo file Main Crea in modo che QRC_ICON32.CPP è disponibile in seguito per tutti i bersagli?

Immagino che una soluzione alternativa sarebbe quella di creare una libreria statica che sarebbe l'unica usando $ {risorse} e quindi collegare quella libreria in tutti i bersagli. Ma ancora, penso che cmake dovrebbe essere in grado di gestire correttamente le sue dipendenze quando si compila con il flag multithreading -j.


.

Per riprodurre il problema, in una cartella vuota, creare un cmakelist.txt contenente il seguente

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})
.

Allora Main1.CPP e Main2.CPP vengono creati utilizzando

#include <iostream>

using namespace std;

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

Il file QRC è

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

Quindi creare una cartella denominata icon32 e aggiungi un'immagine PNG del nome della tua scelta YourImage.png.

Infine, crea una directory di build, inseriscilo ed esegui:

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

L'output dovrebbe essere qualcosa come

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
.

Puoi vedere che QRC_ICON32.CPP viene creato due volte all'incirca allo stesso tempo, nella root della directory di build. I file qrc_icon32.cpp.o però sono creati correttamente nel firsttarget.dir e secondtarget.dir quindi non ci sono conflitti.

Il mio punto è quello che: 1) qrc_icon32.cpp deve essere creato in firsttarget.dir e secondtarget.dir pure o 2) Dovrebbe essere creato nella root della directory di build, ma solo una volta per tutti i bersagli.

È stato utile?

Soluzione

qt5_add_resources scrive il file su CMAKE_CURRENT_BINARY_DIR, non CMAKE_BINARY_DIR

https://qt.gitory. org / qt / qtbase / source / d953d9a4c3bdc5ed3b8d380c4b893b51b523bc50: src / corelib / qt5coremacros.cmake # l205

Idem Qt 4:

http://cmake.org/gitweb?p=cmake.git;a=blob;f=modules/qt4macros.cmake ;h=b1b12d68b07aac076719c681fb844f4f98ba8151 ;hb=head#L212

Aggiornamento:

Con il codice sorgente che hai fornito nel tuo aggiornamento, è possibile vedere il problema.

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

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

http://public.kitware.com/bug/view.php? ID= 12311

La soluzione alternativa è aggiungere un obiettivo personalizzato e aggiungere esplicito dipende da quello.

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)
.

Cmake 3.0 ha una funzione AUTORCC:

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

Mette anche il file QRC_ Generato nella DR di build corrente. Cmake 3.1 lo metterà in una directory specificata da destinazione, rendendo questo problema andare via:

http://cmake.org/gitweb?p= cmake.git; a= commissione; h= 33774CA2

Altri suggerimenti

Il comportamento riportato è dovuto al fatto che QT5_ADD_Resources viene chiamato presto nel processo, durante la configurazione e prima che inizi in realtà la compilazione. A questo punto la variabile $ {cmake_current_binary_dir} sottolineato da Steveire è definita come la cartella di build root . (Questo può essere facilmente testato aggiungendo un messaggio ( output in qt5coremacros.cmake .

L'esito della funzione QT5_ADD_Resources è quello di creare comandi personalizzati che verranno chiamati durante il processo di compilazione: https://qt.gitorious.org/qt /qtbase/source/d953d9a4c3bdc5ed3b8d380c4b893b51b523bc50%3Asrc/corelib/qt5coremacros.cmake#L231

Se vengono definiti più bersagli, tali comandi personalizzati potrebbero essere in seguito vengono chiamati in parallelo allo stesso tempo. In quel momento, il $ {outfile} non verrà ridefinito usando l'allora corrente $ {cmake_current_binary_dir} e quindi i processi paralleli scriveranno nello stesso file nella radice del radice del Build Directory.

Guardando il codice per QT5_ADD_Resources Nessun meccanismo / opzione sembra essere disponibile per correggere tale comportamento in caso di compilazione multithreading, tuttavia, come sottolineato da Steveire, la soluzione alternativa per la funzione di comando personalizzato sottostante può anche essere applicato con successo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top