简体   繁体   中英

resolving linking errors while using Qt with cmake

when I build using the below CMake script, the project builds with no errors.

cmake_minimum_required(VERSION 3.0.0)
project(asdqwdw VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt5 COMPONENTS
    Core
    REQUIRED)
add_executable(${PROJECT_NAME} main.cpp  serv.h serv.cpp)
target_link_libraries(${PROJECT_NAME} Qt5::Core)

but when I use the following CMake script,

cmake_minimum_required(VERSION 3.0.0)
project(asdqwdw VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt5 COMPONENTS
    Core
    REQUIRED)
add_library(SERV serv.h serv.cpp)
target_link_libraries(SERV Qt5::Core)
add_executable(${PROJECT_NAME} main.cpp  ${SERV})
target_link_libraries(${PROJECT_NAME} Qt5::Core)

I get this error,

CMakeFiles/asdqwdw.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x45): undefined reference to `serv::serv(QObject*)'
CMakeFiles/asdqwdw.dir/main.cpp.o: In function `serv::~serv()':
main.cpp:(.text._ZN4servD2Ev[_ZN4servD5Ev]+0xf): undefined reference 
to `vtable for serv' 
collect2: error: ld returned 1 exit status 
make[2]: *** [asdqwdw] Error 1
make[1]: *** [CMakeFiles/asdqwdw.dir/all] Error 2 
make: *** [all] Error 2

is there an explanation as to why I cannot use the latter CMake script instead of the former?


the files are not placed in subdirectories and they are as follows..

main.cpp

#include <QCoreApplication>
#include "serv.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    serv dat;
    return a.exec();
}

serv.h

#ifndef SERV_H
#define SERV_H

#include <QObject>
class serv : public QObject
{
    Q_OBJECT
public:
    explicit serv(QObject *parent = nullptr);

signals:

public slots:
};

#endif // SERV_H

serv.cpp

#include "serv.h"

serv::serv(QObject *parent) :
    QObject(parent)
{

}

Your problem is in your use ofadd_executable

Instead of

add_executable(${PROJECT_NAME} main.cpp  ${SERV})
target_link_libraries(${PROJECT_NAME} Qt5::Core)

Do

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} SERV Qt5::Core)

When you add_library(SERV ... you are creating a TARGET called SERV , not a variable. So first of all, you don't need to use the ${...} around it. Second, you are linking your executable to the target library, not building the target library as part of the executable. That's why we add SERV to the target_add_library() instead of as an argument to add_executable()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM