Cmake как подключить dll
Два дня уже мучаюсь с этой темой. Кое как всё устроил, вот хочу вынести это на Ваше обсуждение чтобы Вы мне посоветовали как всё таки нужно.
Во-первых, помогите определиться на счёт 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 так:
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 .
Читайте также: