I am building qt6 project with cmake. I want to generate a library with QWidget, and the code is:
#ifndef GLOBAL_EXPORTS
#define GLOBAL_EXPORT __declspec(dllexport)
#else
#define GLOBAL_EXPORT __declspec(dllimport)
#endif // !GLOBAL_EXPORTS
class GLOBAL_EXPORT SWidgets : public QWidget
{
Q_OBJECT
public:
SWidgets();
};
In compiling, the vs reports:
unresolved external symbol "public: virtual struct QMetaObject const SWidgets::staticMetaObject"
The bug can be solved by copy moc file. But, it is inconvenient because I have many qt relative library.
In addition, I have add set(CMAKE_AUTOMOC 1)
, and it do not work.
I have upload the code in github (https://github.com/zhang-qiang-github/cmake_qt).
How to solve this bug by cmake? Any suggestion is appreciated~~~
Update: sorry for uploading code to github.
- First, I define my
GLOBAL_EXPORTS
in aGlobal.h
file:
#ifndef GLOBAL_EXPORTS_H
#define GLOBAL_EXPORTS_H
#if (WIN32)
#ifndef GLOBAL_EXPORTS
#define GLOBAL_EXPORT __declspec(dllexport)
#else
#define GLOBAL_EXPORT __declspec(dllimport)
#endif // !GLOBAL_EXPORTS
#else
#define GLOBAL_EXPORT
#endif
#endif
- Then I define my custom widget as:
#ifndef swidget_header_h
#define swidget_header_h
#include "Global.h"
#include <qwidget.h>
#include "qpushbutton.h"
class GLOBAL_EXPORT SWidgets : public QWidget
{
Q_OBJECT
public:
SWidgets();
};
#endif // !swidget_header_h
CodePudding user response:
As @Tsyvarev has pointed out, your handling of the GLOBAL_EXPORTS
definition is wrong.
You should export the symbols if the GLOBAL_EXPORTS
definition is set, therefore it should read (note: I changed #ifndef
to #ifdef
):
#ifdef GLOBAL_EXPORTS
#define GLOBAL_EXPORT __declspec(dllexport)
#else
#define GLOBAL_EXPORT __declspec(dllimport)
#endif // !GLOBAL_EXPORTS
Then in your CMakeLists.txt of the export_dll
project you should add a line defining GLOBAL_EXPORTS
:
set(CMAKE_AUTOMOC 1)
add_library(export_dll SHARED ${SOURCES} ${HEADERS})
set_target_properties(export_dll PROPERTIES COMPILE_DEFINITIONS GLOBAL_EXPORTS)
find_package(Qt6 REQUIRED COMPONENTS Widgets Core Gui)
target_link_libraries(export_dll PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui)
By doing this __declspec(dllexport)
will be added to the symbols when creating the DLL and every consumer of the DLL will automatically get the symbols with a proper __declspec(dllimport)
set.