2017-10-29 7 views
1

私のC++/qtプロジェクトに3つのファイルがあり、私はCMakeを使用しています。QtとCMakeの競合

CMakeListsが含まれています:

cmake_minimum_required(VERSION 3.8) 
project(untitled) 

set(CMAKE_CXX_STANDARD 14) 

set(CMAKE_PREFIX_PATH /Users/username/Qt/5.9.2/clang_64/) 

set(CMAKE_INCLUDE_CURRENT_DIR ON) 
set(CMAKE_AUTOMOC ON) 

find_package(Qt5Core) 
find_package(Qt5Network) 

set(SOURCE_FILES main.cpp server.cpp) 

add_executable(untitled ${SOURCE_FILES}) 

target_link_libraries(${PROJECT_NAME} Qt5::Core) 
target_link_libraries(${PROJECT_NAME} Qt5::Network) 

MAIN.CPPが含まれています

#include <iostream> 
#include <QCoreApplication> 
#include <QtDebug> 
#include "server.cpp" 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication app(argc, argv); 
    MyTcpServer server; 
    return app.exec(); 
} 

、最終的にserver.cppが含まれています

#include <QObject> 
#include <QTcpSocket> 
#include <QTcpServer> 
#include "server.moc" 

class MyTcpServer : public QObject 
{ 
Q_OBJECT 
public: 
    explicit MyTcpServer(QObject *parent = 0); 

public slots: 
    void slotNewConnection(); 
    void slotServerRead(); 
    void slotClientDisconnected(); 

private: 
    QTcpServer * mTcpServer; 
    QTcpSocket * mTcpSocket; 
}; 

MyTcpServer::MyTcpServer(QObject *parent) : QObject(parent) 
{ 
    ... 
} 

void MyTcpServer::slotNewConnection() 
{ 
    ... 
} 

void MyTcpServer::slotServerRead() 
{ 
    ... 
} 

void MyTcpServer::slotClientDisconnected() 
{ 
    mTcpSocket->close(); 
} 
私はいくつかのコードがある。ここにそれをコンパイルしようとしています

CMakeでプロジェクトをコンパイルしようとしていますが、CMakeを実行するとこの問題が発生します:

duplicate symbol __ZN11MyTcpServer18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv in: 
    CMakeFiles/untitled.dir/main.cpp.o 
    CMakeFiles/untitled.dir/server.cpp.o 
         ... 
duplicate symbol __ZN11MyTcpServer16staticMetaObjectE in: 
    CMakeFiles/untitled.dir/main.cpp.o 
    CMakeFiles/untitled.dir/server.cpp.o 
ld: 13 duplicate symbols for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

重複する記号があります。 解決方法

+3

'.cpp'ファイルをインクルードすることは本当に悪い方法です。 'MyTcpServer'クラスの宣言を別のヘッダファイル' server.h'に移動し、 'main.cpp'にインクルードし、' server.coc'から 'server.moc'を取り除くだけです。 – Dmitry

+2

ドミトリーに加えて: 'main.cpp'の' #include "server.cpp"のため、 'server.cpp'の全てが' main.cpp'の一部として1回、 'server.cpp'の'あなたが両方のファイルを 'SOURCE_FILES'としてリストアップしたので、。後者を 'SOURCE_FILES'から削除すると、あなたの問題も解決しますが、ドミトリーが何をしたのかを暖かくお勧めします。 – Scheff

+0

あなたの問題には関係しませんが、 'add_executable'でも' $ {PROJECT_NAME} 'を使うことをお勧めします。これにより、CMakeLists.txtは簡単に再利用できます。 –

答えて

0

.cppファイルには#includeを使用しない方が良いです。定義と宣言を別のファイルに分割することをお勧めします。

(これからの唯一の例外は、PIMPLパターンの場合の民間宣言です。)あなたは、コードの唯一の小片を持っているので、あなたがヘッダーファイルを使用して内のあなたのメソッドを実装分割を避けたい場合には

クラスの定義。

ライブラリが実装されている場合:外部からアクセスできない場合に備えて、ヘッダファイルをインストールしないでください。

関連する問題