Создайте общую библиотеку (.lib и .dll), используя qmake и MSVC2015 - PullRequest
1 голос
/ 22 октября 2019

Я портирую разделяемую библиотеку из 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-файл (<15 КБ). Я попытался добавить <code>CONFIG += static, но при этом был создан файл .lib со всеми символами, а не файлами общей библиотеки, которые я ищу.

Редактировать: После изучения этого вопроса лучше задать вопрос:есть эквивалент qmake (или обходной путь) свойства CMUB PUBLIC_HEADER?

1 Ответ

0 голосов
/ 24 октября 2019

В двух словах: @Matt прав, вам нужно предпринять активные действия в вашем исходном коде для экспорта классов, функций и других символов. Это обязательно в Windows, но также рекомендуется в Unix. Когда компилятор MSVC ++ видит экспортированные символы, он автоматически создает библиотеки импорта .DLL и .LIB.

Чтобы сделать это кросс-платформенным способом с помощью qmake, хорошим руководством будет следовать шаблону QtМастер создания: Добро пожаловать -> Новый проект -> Библиотека -> Библиотека C ++. Расположение проекта ..., имя: 'testlib' (например). Далее, далее, выберите свой комплект, далее и закончите. Файлы, созданные мастером в каталоге проекта:

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

Интересные биты находятся в testlib.pro:

TEMPLATE = lib
DEFINES += TESTLIB_LIBRARY

и заголовке "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

Этот заголовок должен быть включен в другие заголовки, которые будут использовать макрос TESTLIB_EXPORT, подобный этому (testlib.h):

#ifndef TESTLIB_H
#define TESTLIB_H

#include "testlib_global.h"

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

Ключ должен определить TESTLIB_LIBRARY в проекте .proэто создает библиотеку, поэтому макрос TESTLIB_EXPORT определен как Q_DECL_EXPORT, который в Windows определен как __declspec(dllexport), а избегает определения TESTLIB_LIBRARY в проектах с использованием библиотеки. Подробнее об этом здесь .

Теперь вторая часть вашего вопроса. В документации CMake говорится:

PUBLIC_HEADER

Укажите общедоступные заголовочные файлы в целевой папке общей библиотеки FRAMEWORK.

Помечены цели общей библиотекисо свойством FRAMEWORK генерировать фреймворки на macOS, iOS и обычные общие библиотеки на других платформах. Это свойство может быть установлено в список файлов заголовков, которые будут помещены в каталог Headers внутри папки framework. На платформах, отличных от Apple, эти заголовки могут быть установлены с помощью параметра PUBLIC_HEADER для команды install (TARGETS).

Таким образом, атрибут PUBLIC_HEADER предназначен только для установки общедоступных заголовков. Для этого в qmake вам нужно использовать INSTALLS в testlib.pro, например:

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

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