【发布时间】:2017-10-29 09:51:49
【问题描述】:
我的 c++/qt 项目中有 3 个文件,我正在使用 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)
告诉我有一个重复的符号。 如何解决?
【问题讨论】:
-
包含
.cpp文件被认为是一种非常糟糕的做法。只需将MyTcpServer类的声明移动到单独的头文件server.h中,将其包含到main.cpp中并从server.cpp中删除server.moc的包含。 -
除了 Dmitry:由于
main.cpp中的#include "server.cpp",server.cpp中的所有内容都被编译了两次,第一次是main.cpp的一部分,第二次是server.cpp,因为你列出了两者文件为SOURCE_FILES。从SOURCE_FILES中删除后者也可以解决您的问题,但我强烈推荐 Dmitry 所做的。 -
与您的问题无关,但我建议在您的
add_executable中也使用${PROJECT_NAME}。这使得 CMakeLists.txt 更容易重复使用。