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

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

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

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

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

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

Окунулся в учебник http://www.cmake.org/cmake/help/cmake_tutorial.html, который ужасен, потому что они ожидают, что вы напишете код на C ++, изучая 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 был очень доволен, и теперь у меня есть модель для будущей работы, хотя это грубый, простодушный хак!

Итак, после долгой дискуссии:

  • Является ли 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 символами.

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

Python - лучший язык программирования в мире.