Подтвердить что ты не робот

Простой пример использования cmake для создания DLL Windows

Пару лет назад мне было поручено построить и модифицировать этот огромный пакет от партнерского инженерного учреждения, расположенного в NorthEast (возможно, "Down East" ). Этот пакет был создан с использованием чего-то под названием "cmake" с Linux в качестве цели... cmake, IMHO - самая удивительно сумасшедшая, плохо документированная, странно структурированная система сборки. У меня когда-либо было неудовольствие от работы с ограниченными моими способностями (28 лет профессионального опыта работы с системами * NIX и открытым кодом с открытым кодом).

Затем мне пришлось создать еще один проект с "cmake", который предназначался для MSVS. О, РАДОСТЬ! Наконец, ЧТО-ТО, которое могло бы надежно генерировать эти неприятные файлы "проекта" и "решения". И те же самые файлы CMakeLists.txt могут перенаправлять Linux! Ничего себе, я видел свет.

Тем не менее, я все еще довольно темный, где я. Если у меня нет файла CMakeLists.txt для начала, я просто не могу заставить свою голову обернуться, начиная с нуля, и потратить менее одного дня на этот процесс для простейшей проблемы.

У меня есть задача создать DLL с MSVS, к которой можно получить доступ с Python script с использованием ctypes. В основном это означает, что DLL имеет символы на борту. Поскольку у меня есть 10-летняя ошибка, когда мои установки VS 2008 и VS 2010 не могут создать новый проект на С++, я решил, что смогу сделать выбор для создания DLL-решения с помощью cmake.

Мне не удалось найти современный (aka post cmake 2.8.5) COMPLETE пример построения DLL с cmake, который должен быть намного лучше в этой задаче, чем в прошлом.

Dived через учебник http://www.cmake.org/cmake/help/cmake_tutorial.html, который ужасен, потому что они ожидают, что вы напишете код на С++, изучая cmake. (Привет, мужик! У меня достаточно проблем с получением cmake для работы, пусть вместе создаст код, который будет компилироваться!) Учебник идет, строя простой двоичный файл, а затем бинарный, используя библиотеку, но он не генерирует DLL.

Чтение http://www.cmake.org/Wiki/BuildingWinDLL между строками, я наивно добавил некоторый код в файл CMakeLists.txt в каталоге lib:

До:

add_library(MathFunctions mysqrt.cxx)

install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

После:

add_library(MathFunctions SHARED mysqrt.cxx)
GENERATE_EXPORT_HEADER( MathFunctions
             BASE_NAME MathFunctions
             EXPORT_MACRO_NAME MathFunctions_EXPORT
             EXPORT_FILE_NAME MathFunctions_Export.h
             STATIC_DEFINE MathFunctions_BUILT_AS_STATIC
)
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

cmake 3.0.0 и cmake 2.8.12.2 оба крыла в этом файле:

CMake Error at MathFunctions/CMakeLists.txt:2 (GENERATE_EXPORT_HEADER):
  Unknown CMake command "GENERATE_EXPORT_HEADER".

Функция, похоже, находится в установке cmake как GenerateExportHeader.cmake, и никакая отладка не выявила "почему" в этой ошибке. И я не смог найти эту ошибку в Интернете.

И это были первые шесть часов моего дня.

Наконец-то я решил удалить команду оскорбления и попробовать следующее:

add_library(MathFunctions mysqrt.cxx)

install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

Wa-ла! cmake сконфигурирован и сгенерирован, а MSVS успешно его построил, и DLL появилась в подкаталоге Debug каталога библиотеки. Кюель.

Эта DLL, однако, не содержала символов, которые позволяли бы python/ctypes обращаться к желаемой функции. После того, как на странице BuildingWinDLL появилось несколько ссылок, мне удалось вызвать символы. Python был очень доволен, и теперь у меня есть модель для будущей работы, хотя это грубый, простодушный хак!

SO, после долгого обсуждения:

  • Является ли BuildingWinDLL, ссылаясь на cmake 2.8.5 и выше, просто неправильно?
  • Каков был правильный способ сделать это?
  • Есть ли у кого-нибудь простой пример cmake 101 для создания MSVS DLL с экспортированными символами, который не является взломом, чтобы я мог выбросить свой хак?

PS: очень, приятная, дружественная система составления композиции здесь, в stackoverflow. Я буду наслаждаться этим, предполагая, что мне позволено вернуться...

ОБНОВЛЕНИЕ после ответа от steveire:

Первоначальный вопрос ответил, и я вижу, что я пропустил намек на странице BuildingWinDLL. Я также обнаружил, что мне не удалось изменить одно из полей в примере для моего собственного кода.

Итак, теперь мы переходим к следующему слою. Используя ссылочный пример, конструкция решения VS2010 жалуется:

LINK : fatal error LNK1104: cannot open file 'MathFunctions\Debug\MathFunctions.lib'

Я собрал из BuildingWinDLL, что GENERATE_EXPORT_HEADER() был все-пение, все танцы в отношении создания DLL. Файл .lib не генерируется, а генерируемая .dll не содержит символов...

На странице BuildingWinDLL рассказывается о процессе pre-cmake-2.8.5. Процесс 2.8.5, отмеченный в верхней части страницы, - это то, как файлы в нижней части страницы теперь автоматически генерируются с помощью GENERATE_EXPORT_HEADER(). По-прежнему необходимо объединить кусочки вместе, что неясно мне из текста.

Итак, MathFunctions_Export.h генерируется командой cmay GENERATE_EXPORT_HEADER() и конкретными параметрами, представленными здесь, и создает заголовок C с макросом, который вызывает экспорт символов. Этот файл, по-видимому, должен быть явно указан, а символы для экспорта надлежащим образом определены:

#include <math.h>
#include <Mathfunctions/MathFunctions_Export.h>

MathFunctions_EXPORT double mysqrt(double v) {
    return sqrt(v);
}

Добавление атрибута #include и * EXPORT теперь приводит к тому, что символы будут экспортироваться, а VS теперь знает, чтобы сгенерировать .lib и заполнить .dll символами.

УСПЕХ! Спасибо всем, кто помогал в этом процессе и страдал со мной в моей боли.

4b9b3361

Ответ 1

include(GenerateExportHeader)

прежде чем использовать его.

http://www.cmake.org/cmake/help/v3.0/module/GenerateExportHeader.html

CMake создает библиотеки STATIC по умолчанию, поэтому сохраняйте SHARED, если вы хотите создать общую библиотеку.