2014-09-23 46 views
32

我想通過Cmake構建並運行非常簡單和基本的Qt示例,刪除.pro文件。 以下是Qt工程(用於自動生成的Qt工程目錄結構中的代碼是通過CMake實現Qt項目

Cmake (my project name) 
├── headers 
│   └── mainwindow.h 
├── sources 
│   ├── main.cpp 
│   └── mainwindow.cpp 
└── forms 
    └── mainwindow.ui 

mainwindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private: 
    Ui::MainWindow *ui; 
}; 

#endif // MAINWINDOW_H 

mainwindow.cpp

#include "mainwindow.h" 
#include "ui_mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

的main.cpp

#include "mainwindow.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 

這是我的CMakeLists.txt

project(Cmake) 

find_package(Qt5Widgets) 

set(CMAKE_AUTOMOC ON) 
set(CMAKE_INCLUDE_CURRENT_DIR ON) 

QT5_WRAP_CPP(Cmake_hdr_moc mainwindow.h) 
QT5_WRAP_UI(Cmake_form_hdr mainwindow.ui) 

add_library(mainwindow ${Cmake_hdr_moc} ${Cmake_form_hdr}) 
qt5_use_modules(mainwindow Widgets) 

add_executable(Cmake main.cpp mainwindow) 
qt5_use_modules(Cmake Core Gui Widgets) 

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>MainWindow</class> 
<widget class="QMainWindow" name="MainWindow"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>300</height> 
    </rect> 
    </property> 
    <property name="windowTitle"> 
    <string>MainWindow</string> 
    </property> 
    <widget class="QWidget" name="centralWidget"/> 
    <widget class="QMenuBar" name="menuBar"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>29</height> 
    </rect> 
    </property> 
    </widget> 
    <widget class="QToolBar" name="mainToolBar"> 
    <attribute name="toolBarArea"> 
    <enum>TopToolBarArea</enum> 
    </attribute> 
    <attribute name="toolBarBreak"> 
    <bool>false</bool> 
    </attribute> 
    </widget> 
    <widget class="QStatusBar" name="statusBar"/> 
</widget> 
<layoutdefault spacing="6" margin="11"/> 
<resources/> 
<connections/> 
</ui> 

當我生成項目和運行cmake,它指向的文件mainwindow.h表示 'ui_mainwindow.h' 沒有這樣的文件或目錄。

+0

是你的* .ui文件? – Gluttton 2014-09-23 07:47:42

+0

我已經使用.ui文件編輯了帖子。現在我還沒有對該文件進行任何更改,它是自動生成的文件。 – user3877872 2014-09-23 07:53:49

+0

您是在IDE中還是在文件系統中顯示項目的結構? – Gluttton 2014-09-23 08:24:42

回答

55

你的腳本有幾個錯誤,還有一些東西可以改進。更改後it will be樣子:

cmake_minimum_required(VERSION 3.0.2) 
project(MyProject) 

find_package(Qt5Widgets) 

set(CMAKE_AUTOMOC ON) 
set(CMAKE_AUTOUIC ON) 
set(CMAKE_INCLUDE_CURRENT_DIR ON) 

add_library(mainwindow mainwindow.cpp) 
target_link_libraries (mainwindow Qt5::Widgets) 

add_executable(MyProject main.cpp) 
target_link_libraries (MyProject mainwindow) 

錯誤

  1. 錯誤add_executable指令。您嘗試添加庫,但爲此目的,您需要使用target_link_libraries。因此,而不是:

    add_executable(Cmake main.cpp mainwindow) 
    

    您需要:

    add_executable(Cmake main.cpp) 
    target_link_libraries (Cmake mainwindow) 
    
  2. 還有一錯缺少*.cpp文件在add_library指令:

    add_library(mainwindow mainwindow.cpp ${Cmake_hdr_moc} ${Cmake_form_hdr})

Recomendations

  1. 而且設定的CMake版本將是適當的。如果使用CMAKE_AUTOMOC,則需要的版本不低於2.8.6,如果使用CMAKE_AUTOUIC,則需要的版本不低於3.0。2:

    cmake_minimum_required(VERSION 3.0.2) 
    
  2. 使用qt5_wrap_cppCMAKE_AUTOMOC是沒有必要的。

  3. 當您使用CMAKE_AUTOMOC使用CMAKE_AUTOUIC代替qt5_wrap_ui會更合適。

  4. 這個腳本是在文件系統結構如下項目正確:

    Project 
    ├── CMakeLists.txt 
    ├── main.cpp 
    ├── mainwindow.cpp 
    ├── mainwindow.h 
    └── mainwindow.ui 
    

    ,假如你有被@steveire提到你應該使用include_directories另一種結構。

  5. UPD)因爲,我已經寫了這個答案,我認爲它好幾次初學者誰通過CMake嘗試Qt相遇。他們抱怨項目名稱不合適 - 「Cmake」。對於剛剛遇到CMake的初學者很難實現,其中cmake - 僅僅是項目名稱的一部分(並且不是強制性的),並且其中cmake是指令(並且是強制性的)的一部分。所以我想將項目名稱從「Cmake」替換爲「MyProject」。這是減少問題和答案之間的聯繫,但另一方面,這使初學者的答案更加友好。正如由@ErikSjölund提到

  6. UPDqt5_use_modulesis obsoletetarget_link_libraries應改爲使用。

注意:我個人有過不成功的經驗CMAKE_AUTOMOC;對於結構簡單的簡單項目來說很好。我已經受夠了問題的情況下,我的包含文件被存儲在單獨的目錄:

. 
├── include 
│   └── QtClass.h 
└── src 
    └── QtClass.cpp 

而當具有相同名稱的文件被分成不同的子目錄:

. 
├── NamespaceA 
│   ├── QtClass.cpp 
│   └── QtClass.h 
└── NamespaceB 
    ├── QtClass.cpp 
    └── QtClass.h 

最後: 這是建議根據我的個人意見,但我想建議more explicit version腳本不使用CMAKE_AUTOMOCCMAKE_AUTOUIC,它更詳細,但在另一方面你有更多的控制:

cmake_minimum_required (VERSION 2.8.12) 
project (MyProject) 

find_package (Qt5Widgets) 

set (MyProjectLib_src ${PROJECT_SOURCE_DIR}/mainwindow.cpp) 
set (MyProjectLib_hdr ${PROJECT_SOURCE_DIR}/mainwindow.h) 
set (MyProjectLib_ui ${PROJECT_SOURCE_DIR}/mainwindow.ui) 
set (MyProjectBin_src ${PROJECT_SOURCE_DIR}/main.cpp) 

qt5_wrap_cpp(MyProjectLib_hdr_moc ${MyProjectLib_hdr}) 
qt5_wrap_ui (MyProjectLib_ui_moc ${MyProjectLib_ui}) 

include_directories (${PROJECT_SOURCE_DIR}) 
include_directories (${PROJECT_BINARY_DIR}) 

add_library (MyProjectLib SHARED 
    ${MyProjectLib_src} 
    ${MyProjectLib_hdr_moc} 
    ${MyProjectLib_ui_moc} 
) 
target_link_libraries (MyProjectLib Qt5::Widgets) 

add_executable(MyProject ${MyProjectBin_src}) 
target_link_libraries (MyProject MyProjectLib) 

完整版本的項目源代碼可在GitLab獲得。

+0

是的,它解決了,我完全使用了上面的腳本,發現了我想問的問題include_directories($ {PROJECT_BINARY_DIR})是什麼意思?它有什麼作用?我也刪除了add_library。 – user3877872 2014-09-23 08:42:04

+0

'include_directories($ {PROJECT_BINARY_DIR})'對'CMake'說'在構建目錄中查找包含文件。所有生成的文件都被放置到build目錄中。 – Gluttton 2014-09-23 08:43:15

+0

@ user3877872,我已經找到問題的根源,請看我的帖子。 – Gluttton 2014-09-23 08:53:54

0

您沒有向我們展示CMakeLists.txt在目錄結構中的位置。如果是在頂層,那麼你將有

add_executable(Cmake sources/main.cpp sources/mainwindow.cpp) 

,你將需要

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/headers) 

無論如何,找出用戶界面_ *。正在生成.h文件,並與include_directories添加目錄。

+0

當我使用Cmake構建項目時,它顯示目錄結構爲:http:// imgur 。com/nntQ7O5 – user3877872 2014-09-23 08:26:19