Cmake как подключить dll

Обновлено: 06.07.2024

Два дня уже мучаюсь с этой темой. Кое как всё устроил, вот хочу вынести это на Ваше обсуждение чтобы Вы мне посоветовали как всё таки нужно.

Во-первых, помогите определиться на счёт Linux. Если в Windows мне всё понятно, можно один и тот же код собрать и под x86 и под x64 и всё будет работать, так как в составе Windows SDK есть компиляторы и под x86 и x64, да и сама Windows x64 умеет исполнять 32-битные программы. Как дело предстоит тогда с Linux?

Я установил VirtualBox и скачал четыре образа операционных систем: Debian (x86), Deiban (x64), Ubuntu (x86) и Ubuntu (x64). Всё это установил на отдельные виртуальные машины.

Если взять Ubuntu, то у меня одна и та же последовательность действий:

В принципе, ещё ставил:

Но он там не последней версии. Поэтому сейчас попробовал собрать последнюю сборку вручную.

Что касается Debian, то я не нашёл в репозитории пакета libsdl2-dev, поэтому пока всё внимание уделил Ubuntu, там этот пакет есть. Хотя предпочтение я больше отдаю именно Debian, а не Ubuntu. Интерфейс мне там больше нравится.

Установленные заголовочные от libsdl2 я нашёл в /usr/include/. Но вот библиотеки я нигде найти не смог. Куда он устанавливает свои .a и .so файлы?

Под Windows я привык делать следующим образом. У меня есть папка Lib в которое хранятся все использованные мной сторонние библиотеки, которые я не собираю из сходного кода. Вообще сейчас там только две библиотеки: SDL2 (из исходного кода не собираю) и Boost (хоть и собираю её сам, но исходники потом удаляю, потому пусть тут лежит).

Так вот, по каталогам всё разложено так:

То есть раз я могу один и тот же код под Windows собирать и под x86 и под x64, поэтому я и библиотеки вот так разделяю. Ну и от незнания как устанавливаются библиотеки в Linux, и от не знания как собирать и 32-битные и 64-битные программы в 64-битной Linux, я намудрил с CMakeLists.txt файлом. Сейчас для сборки под Windows, в корне репозитория, у меня лежит 4 bat файла: build_x64_debug.bat, build_x64_release.bat, build_x86_debug.bat и build_x86_release.bat. Вот как выглядит один из них:

То есть я через переменные окружения (среды) прописываю пути и необходимые библиотеки. Под Linux у меня только два файла сборки: build_debug.sh и build_release.sh. Хочу сделать по типу как и с Windows - 4 файла сборки, но настроить не могу компиляцию для 32-битного кода из под 64-битной операционной системы. Один из файлов сборки:

Как видно, я указываю тут вручную где лежит только Boost. Опять же, как я понимаю, там лежат библиотеки Boost'а под x64. Собирал я его так:

В то время как под Windows я собирал два раза:

Ну и вот такой вот извращенческий CMake-файл:

Если честно, мне он не очень нравится. Думаю как-то делается по другому. Тем более я так и не понял как у меня проект вообще собрался. Вот исходный код:

Я использую boost::chrono. Под Windows я передаю линковщику библиотеку boost_chrono-vc120-mt-1_57.lib. А под Linux я передаю библиотеку libboost_system.a. Вот с такими параметрами работает. Стоит мне передавать boost_chrono.a, то тут же возникают ошибки. Вот я и в заблуждении, почему под Windows достаточно библиотеки chrono, а под Linux её даже не указываю, а обязательно надо указывать system.

В общем, выслушаю Ваши советы.

s3dworld
> Но вот библиотеки я нигде найти не смог. Куда он устанавливает свои .a и .so
> файлы?
/usr/lib, рядом же всё)

Dimich
> /usr/lib, рядом же всё)
Да я искал там ещё вчера. Сейчас тоже перепроверил. Не нашёл. У меня есть /usr/lib/ и /usr/lib32/, но в них ни одного упоминания на SDL, ни папок, ни файлов с именем SDL. Поэтому и стало интересно куда он их поставил.

Для отладки, и проверки, какие всё-таки пути были сконфигурированы можно писать
message(STATUS "Using SDK libraries from $")

Ныне не очень принято вручную задавать include/lib директории, оставляют это на find_package. Нормальные либы поставляют с собой скрипты для поиска в cmake, для ненормальных увы приходится писать самому, но дело в итоге несложное. Либо оставляют всё на откуп pkgconfig, которым ты и воспользовался для поиска SDL

PS: Иногда удобно конфигурировать проект в ccmake (интерфейс к смаку на ncurses), sudo apt-get install cmake-curses-gui

можешь так же попробовать получить инфу с помощью команды whereis, только не знаю покажет она где либы лежат или нет. Проверить пока не могу, нет линя под рукой

frost
> Для отладки, и проверки, какие всё-таки пути были сконфигурированы можно писать
> message(STATUS "Using SDK libraries from $")
Ну вот я ищу для Linux SDL2 так:

pkg_search_module(SDL2 REQUIRED sdl2)
set(SDL2_INCLUDE_DIR $)
set(SDL2_LIB_NAMES $)

То есть после поиска я имею две переменные: SDL2_INCLUDE_DIRS и SDL2_LIBRARIES. Первая указывает где лежат заголовки, собственно это я и так знаю. А вторая указывает список библиотек для подключения к проекту. Но этот список не содержит полного пути. Так что как узнать путь где лежит библиотека SDL2, я так и не понял.

> Ныне не очень принято вручную задавать include/lib директории, оставляют это на find_package.
Ну и как этот зверь работает? В Windows я знаю где у меня лежат библиотеки. Как его заставить там искать? Имеет ли важность структура в которой у меня лежат библиотеки? Что он в ответ даст? То есть я вообще запутался. Для Windows я имею следующие переменные: SDL2_INCLUDE_DIR, SDL2_LIB_DIR и SDL2_LIB_NAMES. Их я сам придумал и служат они для того, чтобы указывать где лежат исходники, где лежат библиотеки и какие библиотеки надо взять. Как раз всё это совпадает с настройками для проекта Visual Studio: пути для исходников, пути поиска библиотек и дополнительные библиотеки. А для Linux'а как дело обстоит? Сам я эти переменные заполнить не могу, точнее могу только первую и последнюю. А ты говоришь что заполнять их не принято. Так как мне сделать универсальнее чтобы было и под Windows и под Linux, и под x86 и под x64?

s3dworld
А зачем тебе собственно знать где лежат либы SDL?
Такой аргумент в линуксе не прокатывает: -lSDL2 ?

Valorin
> А зачем тебе собственно знать где лежат либы SDL?
Вообще знать мне не обязательно. Просто увидел где заголовки, думал рядом и библиотеки. Порылся, не нашёл. Стало интересно.

> Такой аргумент в линуксе не прокатывает: -lSDL2 ?
Мне вручную указывать это не приходится. Через:

Он нормально ищет SDL2 под Linux. А затем в SDL2_INCLUDE_DIRS и SDL2_LIBRARIES оказываются нужные данные. Собственно потом их я и добавляю:

Проблема в том, что он не ищет таким же способом под Windows. Видимо что-то указывать надо и может ещё и правильно располагать. Да и под Windows нужны же ещё пути к либам. Под Linux я пути к либам не указываю. Вот как сделать универсально?

Как все запущено.. У тебя подход к сборке изначально неверный. Выкинь весь хардкод каталогов сборки типа этого:

В CMake это делается по-другому. Создаешь четыре каталога сборки: debug_x86, release_x86, debug_x64, release_x64. Затем в нужном каталоге генерируешь проект, передавая параметрами соответствующий генератор (x86, x64) и тип сборки (Debug, Release). Например для Release x64 у тебя должен быть примерно такой бат скрипт:

Мусора с установкой переменных окружения также не должно быть - это все разруливается через find_package.

Выбор библиотек нужной разрядности делаешь в самом CMake скрипте. Для этого сначала передаешь в командной строке собственный дополнительный параметр, например BUILD_X64:

Затем в скрипте проверяешь его и выбираешь нужные либы (НЕ проверял, скопипастил кусками с инета):

Что касается линукса, то там тоже можно собирать и 64-разрядные, и 32-разрядные приложения в chroot, но у тебя для этого недостаточный левел красноглазия. Поэтому используй две виртуальные машины с 32- и 64-битными убантами. Соответственно каталоги сборки можешь назвать просто debug и release. Выбор разрядности также не нужен - она всегда будет совпадать с системной.

По SDL2 - опять же, выкинь все что написал, найди в инете какой-нибудь рабочий FindSDL2.cmake, положи себе в проект, пропиши путь к нему через CMAKE_MODULE_PATH и попробуй его прикрутить к основному скрипту. Подключение должно быть аналогично бусту. Как-то так:

Не заведется - попробуй написать свой FindSDL2.cmake. Пособие по написанию Find-скриптов имеется, при знании CMake ничего сложного там нету.

std::noob
Спасибо за ответ! Позже подробно изучу что ты написал, то есть практика. Но для облегчения освоения кое что спрошу. Что Windows, что Linux, в системе, после установки CMake, у неё есть модули. Свой же модуль надо ложить туда же или можно хранить в папке с проектом? И как вообще всё это ищется? Примерчики бы. Например в Windows у меня корень библиотеки SDL2 лежит в E:\Lib\SDL2\, в Ubuntu исходники лежали в /usr/include/,а в Debian лежат в /usr/local/include/. И как всё это искать кодом.

Кстати, в Ubuntu я устанавливал SDL2 через apt-get. В Debian он его там не видит (не apt-get, а пакет SDL2) и пришлось из исходников собрать. Вот он мне туда их сам и поставил (./configure make make install).

Сейчас у меня полный хаус в голове как всё это прописать!

P.S.: У g++ нашёл параметр -m32 и -m64. Попробовал, меняет размер указателя.

s3dworld
> Что Windows, что Linux, в системе, после установки CMake, у неё есть модули.
> Свой же модуль надо ложить туда же или можно хранить в папке с проектом?

Свои модули - всегда в каталоге с проектом. Это часть твоих исходников. Общепринятое имя для каталога со своими CMake-скриптами - cmake. Прописывать его - через CMAKE_MODULE_PATH.

> И как вообще всё это ищется? Примерчики бы.

Как производится поиск? Зависит от конкретного Find скрипта. Скрипты обычно пытаются найти характерные *.h и *.lib (*.so) файлы в общепринятых каталогах. С линуксом попроще, там все лежит в /usr/include и /usr/lib, поэтому проблем при поиске нет. С вантузом все сложнее - там нет стандартного централизованного каталога для инклудов и либ, поэтому без дополнительных телодвижений поиск завершится неудачей. Нужно сложить все либы в какой-то определенный каталог и указать к нему путь через переменную CMAKE_PREFIX_PATH. При этом структура файлов в каталоге должна соответствовать тому, что ожидает Find скрипт. Кстати у тебя например кривая структура каталогов, FindBoost ничего там не найдет. Скачай официальные сборки буста, посмотри как там расположены файлы и сделай у себя точно так же. Обычно получается нечто вроде этого:

> Сейчас у меня полный хаус в голове как всё это прописать!

Ну так читай статьи по CMake, просвещайся. Решай задачу пошагово. Сначала организуй сборку простейшего хелловорлда в разных вариантах на разных ОС. Когда все будет работать, принимайся за подключение буста. А потом уже можно и SDL2 поковырять.

std::noob
> На выходе скрипт должен сформировать переменные SomeLibrary_INCLUDE_DIRS и SomeLibrary_LIBRARIES с путями к хидерам/либам, которые затем передаются в include_directories и target_link_libraries.
А как же на счёт путей к библиотекам? Как раз таки тот самый CMAKE_PREFIX_PATH?

s3dworld
> Например в Windows у меня корень библиотеки

Я завел себе workspace. Это каталог, который содержит в себе все необходимое для сборки проектов (их может быть несколько).

Суть в том, что все внешние библиотеки я собираю из исходников и располагаю готовые сборки в тех местах, куда я сам указал. Не куда попало.

Поэтому строение workspace не зависит от используемой платформы.
Суть в том, что бы рабочее место программиста было единообразным независимо ни от платформы, ни от используемой ИДЕ.

Выше приведенная иерархия каталогов:


Мне не нравится. Внимательный читатель обратит внимание: при такой организации хэдэры библиотек дублируются. Хотя в 99,9% код хэдэров не зависит от адресной модели.

Однако, опытный читатель заметит: даже в таком виде иерархия использует то, что я называю "тэговая конфигурация".

Хороший пример использование тэгов - это библиотека boost.

Рецепт простой: в именах каталогов или файлов мы зашиваем сведения о конфигурации сборки. И в итоге имеем что-то вроде:

workspace
|--- external
| |---msvc-debug-32
. | `--- .
|---mingw-release-64
| `--- .
`---gcc-release-.

Такой workspace способен сочетать внутри себя компоненты самых различных конфигураций сборки, под самые различные компиляторы.
К тому же нет жесткой привязки к какой то одной статичной иерархии каталогов.


Алгоритм поиска один и тот же. По тэгам поисковики разберутся.

Сам же скрипт cmake легко научить понимать тэги, и в зависимости от текущей конфигурации выбирать находить подходящие библиотеки в рамках единого workspace.

Это кардинальным образом решает проблему кросс-платформы.

CMAKE_PREFIX_PATH - это корневой путь, который на винде указывает CMake, где искать хидеры и либы. Без него CMake ничего не найдет. Не будет же он весь диск прошаривать. Внутри этого каталога обычно бывают подкаталоги include и lib. Там скрипты поиска проверяют наличие различных характерных *.h и *.lib файлов. Например у меня скрипт поиска VLC проверяет наличие vlc.h и libvlc.lib. Если эти файлы существуют, то считается что VLC найден. Показываю пример. Допустим есть структура каталогов:

Сначала я указываю корневой путь для find_package:

Затем делаю поиск библиотеки:

После этого вызова появляются две новые переменные со следующими значениями:

Которые передаются в include_directories и target_link_libraries:

Примерно так же работают 99% остальных стандартных Find скриптов. Ставишь CMAKE_PREFIX_PATH, вызываешь find_package, результат передаешь в include_directories и target_link_libraries. Все. А на линуксе даже CMAKE_PREFIX_PATH ставить не нужно, и без него все найдется.

CMake — кроссплатформенная автоматизированная система сборки проектов. Непосредственно сборкой она не занимается, а только генерирует Makefile, который потом будет выполнен утилитой make.

CMake может проверять наличие необходимых библиотек и подключать их, собирать проекты под разными компиляторами и операционными системами. Т.е. у вас есть куча кода и файлик, содержащий информацию для cmake, и чтобы скомпилить это дело где-нибудь еще, вам нужно просто запустить там cmake, который сделает всё сам. Удобно, полезно, просто.

Если нет желания/времени/сил читать весь туториал и Вы используете какой-нибудь QtCreator (или любая другая IDE, умеющая работать с cmake), то:

  • Создайте в IDE проект под cmake
  • Найдите в папке с проектом CMakeFiles.txt
  • Пробегитесь глазами по туториалу, соотнося его с вашим CMakeFiles.txt

Про подключение библиотек рекомендуется все-таки прочитать целиком.

Предположим, у Вас есть исходничек "test.cpp" (// а если нет?)(А если нет, то CMake тебе трогать рано). Для начала нужно создать файлик для cmake, который обычно называют "CMakeLists.txt", и написать туда вот это:

Теперь запускаем (из консоли) в этой папке команду "cmake CMakeLists.txt" (аргументом можно передавать не только файл, но и директорию, в которой он лежит, тогда cmake найдет его сам).

cmake будет использовать переданный (или найденный) файл проекта (тот самый CMakeLists.txt), и в текущей директории будет создавать проект. Проект - это много-много файлов и директорий (примечание: поэтому лучше запускать cmake из другой директории, чтобы можно было, например, быстро удалить все бинарники), из которых нас больше всего интересует Makefile.

Makefile - это файл, нужный для утилиты make. Именно она запускает компиляторы, линковщики и прочие радости. Запускаем make в каталоге сборки (т.е. там же, где Вы запускали cmake). В консоли вылезет примерно такой текст:

А у Вас в папочке появится исполняемый файл "test". Запустите, убедитесь, что это действительно то, что ожидается от компиляции файла "test.cpp".

Поразбираемся с различными возможностями cmake.

Указывайте высокую минимальную версию CMake. Если используемая версия cmake меньше 2.6, он не захочет работать. Писать эту команду всегда - хороший стиль (cmake будет пыхтеть и обижаться, если вы не укажете версию, но собирать всё равно всё будет).

Указывает, что этот cmake-файл является корневым для некоторого проекта. С проектами связаны определенные переменные и поведение cmake (читайте документацию).

В cmake можно создавать текстовые переменные. Команда

запишет в переменную "VARIABLE" значение "The variable's value". Чтобы где-либо использовать значение этой переменной, нужно написать $.

Чтобы добавить к переменной некий текст, можно сделать так:

Как видите, использовать значение можно и внутри кавычек. Переменные активно используются различными библиотеками - для установки флагов, параметров сборки/линковки и прочих вкусностей, об этом чуть-чуть попозже.

Пример коше'гного проекта со списком сорцов в отдельной переменной:

Эта команда добавит к флагам, используемым при сборке c++-кода, флаги -std=c++11 и -Wall.

Кто не знает: "-std=c++11" включает в gcc поддержку стандарта c++11, "-Wall" говорит gcc выводить все предупреждения (очень советую, помогает отловить много глупых багов и писать аккуратный код).

Если ваша версия GCC меньше, чем 4.7.0, вместо -std=c++11 нужно использовать -std=c++0x.

В GCC 4.8.0 появился флаг -std=c++1y, в котором начинают реализовывать фичи следующего стандарта.

Надеюсь, и это понятно.

Научимся искать и подключать библиотеки при помощи cmake на примере Boost. Для начала установим переменные для буста:

Итак, мы установили флаги. Давайте найдем буст!

Допустим, нам нужны компоненты буста под названием chrono (библиотека для работы со временем) и filesystem (библиотека для работы с файловой системой):

Win, будут искаться только нужные библиотеки, и их расположение будет записано в переменную Boost_LIBRARIES.

Опция "REQUIRED" говорит о том, что библиотека необходима проекту. Без нее cmake решит, что отсутствие данной библиотеки - не так уж и страшно, и будет собирать дальше.

Добавим директории с хедерами буста для поиска в них хедеров:

Итак, осталось найденные библиотеки подключить к исполняемому файлу.

В качестве библиотек нужно указать пути к необходимым собранным библиотекам. cmake нашел указанные нами библиотеки и записал в переменную, чем мы и пользуемся.

Заметим, что эту команду нужно вызывать после того, как создан target сборки (через add_executable).

Итак, полный пример использования всего этого. У нас есть некая директория (отныне считаем ее "/sources"), и в ней лежат исходники

В корне "/" лежит файл "/CMakeLists.txt":

Если Вам что-то в нём не понятно - перечитайте соответствующую информацию выше.

Создаем директорию "/build" (не "/sources/build"), переходим в нее, запускаем в ней "cmake ..". ".." - метка родительской директории. cmake возьмет из нее наш CMakeLists.txt и по нему создаст проект в папке "/build". Чтобы проект собрать, запускаем "make" в той же папке "/build".

Таким образом, в корне у нас есть:

  • CMakeLists.txt
  • директория с исходниками
  • каталог сборки

Все разделено, автоматизировано и удобно.

Пусть в ./ лежит основной проект, а в ./subdir мы хотим сделать либу, а в ./build построить проект.

В ./build запускаем "cmake .. && make" и получаем собранный проект.

Интеграция с cmake у QtCreator не очень тесная, тем не менее, работать с ним можно.

Создаем новый проект без использования Qt, выбираем "Проект на С++ с использованием CMake". Создастся дефолтный файл сборки, который просто добавляет все исходники в директории проекта и компилирует их в один бинарник.

Как использовать CMake для импорта сторонних библиотек в CLion

CMake - это кроссплатформенный инструмент для установки (компиляции), вы можете простыми предложениями описать установку (процесс компиляции) всех платформ. Он может выводить различные файлы сборки или проекта, а такжетестФункции C ++, поддерживаемые компилятором, аналогичны функциям automake в UNIX.

Как использовать CMake

Все операторы CMake записываются в файл с именем CMakeLists.txt. Когда файл CMakeLists.txt подтвержден, вы можете использовать команду ccmake для настройки соответствующих значений переменных. Эта команда должна указывать на каталог, в котором находится CMakeLists.txt. После завершения настройки используйте команду cmake для создания соответствующего make-файла (в Unix-подобной системе) или файла проекта (при компиляции с помощью соответствующего инструмента программирования под окном).

Базовый рабочий процесс:

Где каталог - это каталог, в котором находится CMakeList.txt;

  • Первый оператор используется для настройки параметров компиляции, таких как каталог VTK_DIR. Как правило, этот шаг не требует настройки, просто выполните второй оператор напрямую, но при возникновении ошибки вам необходимо рассмотреть конфигурацию здесь, и этот шаг действительно пригодится ;
  • Вторая команда используется для создания файлов Makefile в соответствии с CMakeLists.txt;
  • Третья команда используется для выполнения файла Makefile, компиляции программы и создания исполняемого файла;

Выполнение CMake очень простое. Сложность заключается в том, как написать файл CMakeLists.txt. Ниже приводится краткое введение в подготовку файла CMakeLists.txt с примером. Посмотрите на следующий файл CMakeLists.txt.

Или используйте следующий CMakeLists.txt

Вторая строка указывает, что сгенерированный проект называется test_math.

Строка 4 определяет каталог файла заголовка как включаемый

Строка 8 указывает каталог исходного файла как src и назначает его переменной окружения DIR_SRCS.

Строка 10 устанавливает значение переменной среды TEST_MATH равным значению переменной среды DIR_SRCS, здесь используется, чтобы показать, как использовать переменные среды для присвоения значений переменным среды.

Строка 14 назначает библиотеку математических функций переменной среды LIBRARIES. Конечно, эту переменную среды можно не указывать, а имя библиотеки можно использовать непосредственно позже.

Строка 18 используется для указания сгенерированного файла, компиляции всех файлов в каталоге переменной среды TEST_MATH для создания исполняемого файла bin в каталоге ../bin

В 20-й строке указано, что библиотека компоновки при выполнении ../bin/bin является значением переменной среды LIBRARIES-libm.so.

Поместите CMakeLists.txt в текущий каталог и выполните CMakeLists.txt

Вы можете сгенерировать исполняемый файл, файл bin в каталоге / bin, и запустить его, чтобы увидеть, соответствует ли результат ожидаемому.

1. Основное использование

Установка: После загрузки бинарного пакета его можно сразу распаковать и использовать.

Чтобы установить из исходного кода, выполните команду: ./bootstrap; make; make install-failed to try to run bootstrap.

Используйте: cmake dir_path, сгенерируйте файлы проекта или файлы makefile

Во-вторых, концепция

out-of-sourceСборка, в отличие от сборки из исходного кода, то есть размещение скомпилированных выходных файлов и исходных файлов в разных каталогах;

В-третьих, основная структура

1. Положитесь на файл CMakeLists.txt, можно указать одну главную цель проекта и подкаталоги, включенные в основной каталог;

2. Используйте проект, чтобы указать имя проекта в CMakeLists.txt проекта, add_subdirectory, чтобы добавить подкаталоги

3. Подкаталог CMakeLists.txt унаследует настройки родительского каталога CMakeLists.txt (подлежит проверке).

4. Грамматика

2. Переменные: используйте команду set для явного определения и присвоения значений. В операторах, отличных от if, используйте $ <> для ссылки и напрямую используйте имена переменных в операторах if; последующие команды set очистят исходное значение переменной;

6. Условное заявление:

7. Заявление цикла

8. Заявление о петле

V. Внутренние переменные

CMAKE_C_COMPILER: Укажите компилятор C

CMAKE_CXX_COMPILER:

CMAKE_C_FLAGS: Параметры при компиляции файлов C, такие как -g; вы также можете добавить параметры компиляции через add_definitions

EXECUTABLE_OUTPUT_PATH: Путь хранения исполняемого файла

LIBRARY_OUTPUT_PATH: Путь к файлу библиотеки

CMAKE_BUILD_TYPE:: Тип сборки (Отладка, Выпуск, . ), CMAKE_BUILD_TYPE = Отладка

BUILD_SHARED_LIBS:Switch between shared and static libraries

Использование встроенных переменных:

>> Укажите в CMakeLists.txt, используйте set

>> Используется в команде cmake, например cmake -DBUILD_SHARED_LIBS = OFF

В-шестых, порядок

>> Используйте $ , чтобы указать корневой каталог проекта.

include_directories: Укажите путь поиска файла заголовка, что эквивалентно указанию параметра -I в gcc

link_directories: Путь поиска библиотеки динамической компоновки или библиотеки статической компоновки, что эквивалентно параметру -L в gcc

add_subdirectory: Содержит подкаталоги

add_executable: Скомпилируйте исполняемую программу, укажите компиляцию, вроде можно добавить файл .o

add_definitions: Добавить параметры компиляции

>> add_definitions (-DDEBUG) добавит определение макроса DEBUG в командную строку gcc;

>> add_definitions( “-Wall -ansi –pedantic –g”)

target_link_libraries: Добавить библиотеку ссылок, как при указании параметра -l

add_library:

add_custom_target:

message( status|fatal_error, “message”):

set_target_properties( . ): lots of properties. OUTPUT_NAME, VERSION, .

link_libraries( lib1 lib2 . ): All targets link with the same set of libs

Семь, описание

1. Makefile, созданный CMAKE, может обрабатывать изменение файла .h и компилировать только необходимый файл cpp;

8. FAQ

1) Как получить все исходные файлы в каталоге

>> Сохраните все исходные файлы (кроме файлов заголовков) в каталоге в переменной, а затем используйте add_executable (ss7gw $ ).

2) Как указать цель компиляции проекта

>> Обозначение команды проекта

3) Как добавить динамические и статические библиотеки

>> Добавьте команду target_link_libraries

>> message([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" . )

>> Обратите внимание на корпус

5) Как указать заголовочный файл и путь к файлу библиотеки

>> include_directories и link_directories

>> Может вызываться несколько раз для установки нескольких путей

>> link_directories влияет только на цели, стоящие за ним

6) Как отличить отладочную версию от релизной

>> Создайте два каталога отладки / выпуска, соответственно выполните в них cmake -DCMAKE_BUILD_TYPE = Debug (или Release). Когда вам нужно скомпилировать разные версии, введите разные каталоги и выполните make;

Версия отладки будет использовать параметр -g; версия выпуска будет использовать -O3 -DNDEBUG

>> Другой способ настройки - например, версия DEBUG для установки параметров компиляции DDEBUG

Просто добавьте параметры при выполнении cmake, например cmake -D DEBUG_mode = ON

7) Как установить условную компиляцию

НапримерВ отладочной версии устанавливается параметр компилятора DEBUGИ изменения не должны менять CMakelist.txt

>> Используйте команду option, например:

option(DEBUG_mode "ON for debug or OFF for release" ON)

>> Как сделать его эффективным: сначала cmake генерирует make-файл, а затем make edit_cache для редактирования параметров компиляции;LinuxЗатем откроется текстовое поле, вы можете изменить его, а затем make для генерации целевого файла после того, как это будет сделано - emacs не поддерживает make edit_cache;

>> Ограничения: этот метод не может напрямую установить сгенерированный make-файл, но должен использовать команды для установки параметров перед make; для отладочной и выпускной версий это эквивалентно двум каталогам: cmake и make edit_cache соответственно;

>> Желаемый эффект: напрямую указать элемент переключения через параметр при выполнении cmake и сгенерировать соответствующий make-файл - это можно сделать, например, cmake -DDEBUGVERSION = ON

8) Как добавить определение макроса компиляции

>> Используйте команду add_definitions, см. Описание раздела команд

9) Как добавить зависимости компиляции

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

10) Как указать целевой каталог документов

>> Создайте новый каталог, выполните cmake в каталоге для создания файла Makefile, чтобы результат компиляции был сохранен в этом каталоге, аналогичном

11) Папок много, нужно ли каждую папку собирать в файл библиотеки?

>> Вы не можете использовать CMakeList.txt в подкаталоге, а напрямую указывать подкаталог в верхнем каталоге

12) Как установить зависимую версию cmake

13) Как указать относительный путь

>> $ представляет корневой каталог исходного файла, $ представляет корневой каталог двоичного файла?

14) Как настроить каталог для компиляции промежуточных файлов

15) Как использовать сравнение строк или чисел в предложениях IF

>> Сравнение чисел LESS, GREATER, EQUAL, сравнение строк STRLESS, STRGREATER, STREQUAL,

IF(AAA STREQUAL abc)

16) Компилировать ли только необходимые файлы cpp при изменении файла h

17) На машине установлены VC7 и VC8, CMAKE автоматически выполнит поиск компилятора, но как указать определенную версию?

18) Как указать параметры компиляции в зависимости от ОС

>> IF( APPLE ); IF( UNIX ); IF( WIN32 )

19) Могут ли некоторые команды до и после компиляции выполняться автоматически?

>> Да, подлежит уточнению

20) Как распечатать вывод make

Интеллектуальная рекомендация


Michael.W Поговорите о Hyperledger Fabric. Проблема 20 - Подробная индивидуальная сортировка узла с пятью порядками с исходным кодом для чтения.

Michael.W Поговорите о Hyperledger Fabric. Проблема 20 - Подробная индивидуальная сортировка узла с пятью порядками с исходным кодом чтения Fabric Файл исходного кода одиночного режима находится в ord.


Мяу Пасс Матрица SDUT

Мяу Пасс Матрица SDUT Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description Лянцзян получил матрицу, но эта матрица была особенно уродливой, и Лянцзян испытал отвращение. Чт.


Гессенская легкая двоичная структура удаленного вызова

Hessian - это легкая двоичная структура удаленного вызова, официальный адрес документа, в основном он включает протокол удаленного вызова Hessian, протокол сериализации Hessian, прокси-сервер клиента .


TCP Pasket и распаковка и Нетти Solutions

Основные введение TCP является ориентированным на соединение, обеспечивая высокую надежность услуг. На обоих концах (клиенты и терминалы сервера) должны иметь один или более гнезда, так что передающий.

Как заставить CMake связать исполняемый файл с внешней общей библиотекой, которая не построена в том же проекте CMake?

Просто выполнение target_link_libraries(GLBall $/res/mylib.so) дает ошибку

после того, как я скопировал библиотеку в двоичный каталог bin/res .

Я пробовал использовать find_library(RESULT mylib.so PATHS $/res)

Что терпит неудачу с RESULT-NOTFOUND .

Сначала установите путь поиска библиотек:

А потом просто сделай

Использование link_directories не рекомендуется даже в собственной документации. Я думаю, что здесь было бы лучше разрешить неудачный find_library вызов в исходном вопросе или использовать решение @Andre. Я считаю, что цель «импортированной» библиотеки более надежна, поскольку она нацелена на расположение конкретной библиотеки, а не просто дает глобальный путь поиска. См. Ответ Андре. Вы всегда должны использовать find_library и использовать этот путь вместо жесткого его кодирования, см. мой ответ .

Ответ стрелка верен и во многих случаях предпочтителен. Я просто хотел бы добавить к его ответу альтернативу:

Вы можете добавить "импортированную" библиотеку вместо каталога ссылок. Что-то вроде:

А затем сделайте ссылку, как если бы эта библиотека была создана вашим проектом:

Такой подход даст вам немного больше гибкости: обратите внимание на команду add_library () и множество целевых свойств, связанных с импортированными библиотеками .

Не знаю, решит ли это вашу проблему с «обновленными версиями библиотек».

Вероятно, это будет, add_library( mylib SHARED IMPORTED ) иначе вы получите add_library called with IMPORTED argument but no library type ошибку вам нужно добавить GLOBAL после, IMPORTED если вы хотите получить доступ к импортированной библиотеке в каталогах выше текущей: add_library(breakpad STATIC IMPORTED GLOBAL) @Andre IMPORTED_LOCATION, похоже, требует путь к файлу вместо каталога, содержащего файл @SOUser: Да, IMPORTED_LOCATION должен указывать на файл, а не на каталог. Я исправил это, думаю, автор не будет жаловаться.

Я предполагаю, что вы хотите создать ссылку на библиотеку с именем foo , ее имя файла обычно является ссылкой foo.dll или libfoo.so .

1. Найдите библиотеку.
Вы должны найти библиотеку. Это хорошая идея, даже если вы знаете путь к своей библиотеке. CMake выдаст ошибку, если библиотека исчезла или получила новое имя. Это помогает обнаружить ошибку на раннем этапе и дать понять пользователю (а может и самому себе), что вызывает проблему.
Чтобы найти библиотеку Foo и сохранить путь в FOO_LIB использовании

CMake сам определит фактическое имя файла. Он проверяет обычные места, такие как /usr/lib , /usr/lib64 и пути внутрь PATH .

Вы уже знаете, где находится ваша библиотека. Добавьте его CMAKE_PREFIX_PATH при вызове CMake, тогда CMake также будет искать вашу библиотеку в переданных путях.

2. Свяжите библиотеку с 1. у вас есть полное имя библиотеки FOO_LIB . Вы используете это, чтобы связать библиотеку с вашей целью, GLBall как в

Если вы не добавите один из этих описателей видимости, он будет вести себя как PRIVATE или PUBLIC , в зависимости от версии CMake и установленных политик.

3. Добавить включает (этот шаг может быть необязательным).
Если вы также хотите включить файлы заголовков, используйте find_path аналогичные find_library и найдите файл заголовка. Затем добавьте каталог include с target_include_directories похожими на target_link_libraries .

Если доступно внешнее ПО, можно заменить find_library и find_path на find_package .

Читайте также: