使用 qmake 和 MSVC2015 创建共享库(.lib 和 .dll)

Create shared library (.lib and .dll) using qmake and MSVC2015

我正在将一个共享库从 CMake 移植到 QMake(以便更好地与我们的代码库的其余部分集成),并且在 Windows 中遇到问题让 qmake 生成 .lib 和 .dll 文件. 我已将其移植到 Linux 和 MacOS(使用 Unix 共享库格式更容易),但在使用 Windows.

时遇到问题

请注意,我使用的不是 Mingw 编译器,而是 MSVC 2015 编译器。不幸的是,由于各种原因,我无法使用 Mingw 编译器。

我的.pro文件中的相关代码:

Qt -= core gui #not using the qt library
CONFIG += c++14 warn_on
TEMPLATE  = lib
TARGET = MyLibrary

使用 CMake,我能够将某些 .h 文件设置为 PUBLIC_HEADER 文件,并且在 运行 make install 之后,它生成了正确的 .lib 和 .dll 文件。

但是使用 qmake,它只生成了一个非常小的 .dll 文件 (<15kb)。我尝试添加 CONFIG += static 但创建了一个包含所有符号的 .lib 文件,而不是我要查找的共享库文件。

编辑:在深入研究之后,一个更好的问题可能是: 是否有 CMake 的 PUBLIC_HEADER 属性 的 qmake 等价物(或解决方法)?

简而言之:@Matt 是对的,您需要在源代码中采取积极行动来导出 类、函数和其他符号。这在 Windows 中是强制性的,但在 Unix 中也是推荐的做法。当 MSVC++ 编译器看到导出的符号时,它会自动创建 .DLL 和 .LIB 导入库。

要使用 qmake 以 cross-platform 方式执行此操作,一个很好的指南是遵循 Qt Creator 向导的模式:欢迎 -> 新建项目 -> 库 -> C++ 库。项目位置...,名称:'testlib'(例如)。下一步,下一步,选择你的工具包,下一步,完成。向导在项目目录中创建的文件是:

testlib.cpp
testlib_global.h
testlib.h
testlib.pro
testlib.pro.user

有趣的部分在 testlib.pro:

TEMPLATE = lib
DEFINES += TESTLIB_LIBRARY

还有 header "testlib_global.h"

#ifndef TESTLIB_GLOBAL_H
#define TESTLIB_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(TESTLIB_LIBRARY)
#  define TESTLIB_EXPORT Q_DECL_EXPORT
#else
#  define TESTLIB_EXPORT Q_DECL_IMPORT
#endif

#endif // TESTLIB_GLOBAL_H

这个 header 应该包含在其他 header 中,这将使用像这样的 TESTLIB_EXPORT 宏 (testlib.h):

#ifndef TESTLIB_H
#define TESTLIB_H

#include "testlib_global.h"

class TESTLIB_EXPORT Testlib
{
public:
        Testlib();
        // ...
};

关键是在建库的工程.pro中定义TESTLIB_LIBRARY,所以TESTLIB_EXPORT宏定义为Q_DECL_EXPORT,在Windows中是定义为 __declspec(dllexport),并且 避免 在项目 使用 库中定义 TESTLIB_LIBRARY。有关此内容的更多信息 here

现在,你的问题的第二部分。在 CMake documentation 中,它表示:

PUBLIC_HEADER

Specify public header files in a FRAMEWORK shared library target.

Shared library targets marked with the FRAMEWORK property generate frameworks on macOS, iOS and normal shared libraries on other platforms. This property may be set to a list of header files to be placed in the Headers directory inside the framework folder. On non-Apple platforms these headers may be installed using the PUBLIC_HEADER option to the install(TARGETS) command.

因此 PUBLIC_HEADER 属性仅与安装 public header 相关。要在 qmake 中这样做,您需要在 testlib.pro 中使用 INSTALLS,例如:

unix {
    target.path = /usr/local/lib
    headers.path = /usr/local/include
}
!isEmpty(target.path) {
    INSTALLS += target
}

headers.files = $$HEADERS
!isEmpty(headers.path) {
    INSTALLS += headers
}