LINUX.ORG.RU

Почему в cmake всё так сложно?

 


2

3

внутри обычного Makefile я могу просто написать

cc -std=c99 file.c -o program -lasound
либо
cc -std=c99 file.c -o program `pkg-config --libs alsa`


что нужно сделать в таком случае для cmake?

текущее содержимое CMakeLists.txt
cmake_minimum_required(VERSION 3.2)
project(program C)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")

set(SOURCE_FILES
    file.c)

add_executable(program ${SOURCE_FILES})

Возникает желание выбросить на помойку этот cmake... документация в стиле «хрен поймешь без бутылки», вот так сразу ее не взять чтобы «прочитал -> сразу понял -> используешь». Туториалы не объясняют что к чему.

ЛОР, помоги.


З.Ы. program и file.c - нарочно измененные имена. Добавление -lasound после -std=c99 не приводит к какому-либо результату.

★★★★★

Последнее исправление: reprimand (всего исправлений: 2)

CMake — неочевидное говно потому что.

cmake_minimum_required(VERSION 3.2)
project(program C)

set_property(TARGET program PROPERTY C_STANDARD 99)

set(SOURCE_FILES
    file.c)

link_directories(/usr/lib)

add_executable(program ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(program asound)
EXL ★★★★★
()
Ответ на: комментарий от EXL

link_directories(/usr/lib)

ОМГ, да они там совсем поехавшие

если надо это вручную указывать, зачем тогда вообще нужен этот cmake?

reprimand ★★★★★
() автор топика

))))

все врно,но как «монстроузный сборщик на шаблонах проекта с сотней файлов»-можно использовать

но когда через год два или просто чужой проект на смейке надо менять конфиги-то это просто ад

порой смена смейк конфига(который в сотнях файлах-шаблонах) может занять времени дольше чем написание конфига сборки с нуля

anonymous
()
Ответ на: комментарий от anonymous

как «монстроузный сборщик на шаблонах проекта с сотней файлов»-можно использовать

когда через год два или просто чужой проект на смейке надо менять конфиги-то это просто ад

получается, что таки использовать нельзя? или можно?

ОФФТОПИК: глазами видел толстые монструозные проекты на одних только мейкфайлах, и ничего, как-то живут...

reprimand ★★★★★
() автор топика
Ответ на: комментарий от reprimand

если надо это вручную указывать, зачем тогда вообще нужен этот cmake?

Это просто для примера, если библиотека «системная», то можно не указывать вообще.

EXL ★★★★★
()
Ответ на: комментарий от EXL

угу, уже заметил

кстати, set_property корректно работает если разместить после add_executable

иначе ругается на

Error:set_property could not find TARGET program. Perhaps it has not yet been created.

а еще, не знаешь как грамотно указывать -Wall и -Werror?

reprimand ★★★★★
() автор топика
Ответ на: комментарий от reprimand

Кстати set_property(TARGET program PROPERTY C_STANDARD 99) только недавно ввели, то этого нужно было делать такой костыль:

macro(use_c99)
  if (CMAKE_VERSION VERSION_LESS "3.1")
    if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
      set (CMAKE_C_FLAGS "--std=gnu99 ${CMAKE_C_FLAGS}")
    endif ()
  else ()
    set (CMAKE_C_STANDARD 99)
  endif ()
endmacro(use_c99)

Увы, ничего лучше говноCMake'а так и не придумали. QBS вот неплохой, не использует тот же make, а компилит сам в несколько потоков. Но там Qt, сам понимаешь.

EXL ★★★★★
()
Ответ на: комментарий от reprimand

кстати, set_property корректно работает если разместить после add_executable

Ага, я на память писал. Уже не помню всех этих херанутых премудростей CMake'а.

а еще, не знаешь как грамотно указывать -Wall и -Werror?

Костылями конечно же, добро пожаловать в CMake.

http://stackoverflow.com/a/3818084
http://stackoverflow.com/a/33266748

EXL ★★★★★
()
Ответ на: комментарий от EXL

ужас какой

ничего лучше говноCMake'а так и не придумали

нуу, если компилить только под UNIX системы, то make устраивать должен вполне

reprimand ★★★★★
() автор топика
Ответ на: комментарий от EXL

Увы, ничего лучше говноCMake'а так и не придумали.

Давно есть GNU Make со встроенным Guile.

tailgunner ★★★★★
()
Ответ на: комментарий от EXL

CMake обычно используют кросс-платформенные проекты.

Я его юзаю только потом, что Clion под него заточен, а лучшего IDE я пока не нашел (сейчас в треде появятся адепты [g]vim + cscope).

Конечно, я могу переключаться в консольку и выполнять make, но блин... 21 век на дворе!

reprimand ★★★★★
() автор топика
Ответ на: комментарий от reprimand

а лучшего IDE я пока не нашел

Qt Creator, к примеру. Кроме CMake держит Makefile, QMake, QBS, Autotools. Для сишки/плюсов отличное и легковесное IDE. Хотя бы не тормозит, как этот самый CLion.

EXL ★★★★★
()
Ответ на: комментарий от reprimand

нуу, если компилить только под UNIX системы, то make устраивать должен вполне

От сложности проекта зависит. Всякие автотулзы не на ровном месте выросли же.

devsdc ★★
()
Ответ на: комментарий от reprimand

да они там совсем поехавшие

Тебе просто странный совет дали.

project(program C)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")

find_package(PkgConfig REQUIRED)
pkg_check_modules(ALSA alsa REQUIRED)

set(SOURCE_FILES
    file.c)

include_directories(${ALSA_INCLUDE_DIRS}) # у некоторых библиотек заголовки в отдельной поддиректории
link_directories(${ALSA_LIBRARY_DIRS}) # некоторые библиотеки сами в каких-то поддиректориях лежат

add_executable(program ${SOURCE_FILES})
target_link_libraries(program ${ALSA_LIBRARIES})

pkg_check_modules может сразу много pkg-config модулей за раз искать.

Для некоторых библиотек есть готовые скрипты, как для pkg-config. Тогда используешь find_package(), с параметрами из описания тех скриптов. Например:

find_package(Boost COMPONENTS
    filesystem
    program_options
    signals
    system
    thread
    REQUIRED)

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)

CMake и правда несколько долбанут. Писали админы похоже. Попахивает башом и перлятиной.

hlamotron
()

Ну не всё так плохо. Мой cmake за полчаса научился сам выкачивать и собирать зависимость основного проекта, а там autotools было в то время (сейчас cmake), причём мне на самом деле пришлось почитать документацию. Из того, что ты пообсираешь лучшую на сегодняшний систему сборки из представленных, ничего хорошего не выйдет.

anonymous
()
Ответ на: комментарий от reprimand

а еще, не знаешь как грамотно указывать -Wall и -Werror?

На выбор.

  • Полная форма:
    set_property(TARGET program
                 APPEND
                 PROPERTY COMPILE_OPTIONS -Wall -Werror)
    
  • Для конкретной цели (но не добавление, а замена):
    target_compile_options(program -Wall -Werror)
    
  • Для всего в текущей директории (добавление):
    add_compile_options(-Wall -Werror)
    

Вышеприведённое для флагов компилятора. Для препроцессора COMPILE_DEFINITIONS, target_compile_definitions() и add_definitions(). И так далее с include_directories, link_directories и link_libraries.

Про pkg-config уже написали.

Про -std= можно через свойство C_STANDARD, если нужно 1) кроссплатформенно и 2) чтобы оно само проверило поддержку стандарта, а можно как написано выше, если переносимость на !GCC не важна.

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

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 4)
Ответ на: комментарий от intelfx

Ниже просмотри тред.

Я вставил link_directories(/usr/lib) специально, чтобы ТС в будущем не задавал вопросов, мол как подлинковать библиотеку из соседнего каталога, не устанавливая её в систему.

PkgConfig — хорошо, но только в GNU/Linux. CMakeLists.txt, наводнённый лапшой из pkg_check_modules по опыту KDE'шников весьма паршиво работает в том же MS Windows. А CMake задумывался как кросс-платформенная система сборки.

EXL ★★★★★
()
Ответ на: комментарий от intelfx

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

AHAHAHAHAHA_OH_WOW.jpg

CMake настолько удобный, очевидный и понятный, что на ЛОРе каждый месяц появляются треды с его обосрамсами, вот, недавний, майский: Cmake Qt 5.6 undefined reference to vtable

TL;DR: Проект не собирается, если *.cpp и *.h лежат в разных директориях.

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)

документация в стиле

«краткость - сестра таланта» (c). Да, хотелось бы подробнее.

С моей точки зрения главная проблема cmake в отличие от autotools - это отсутствие шаблонов ну или отсутствие устоявшихся правил создания CMakeLists.txt. В autotools синтаксис m4 непривычен, но зато какой бы проект ни открыл, быстро понятно, что и где править. А открыл CMakeLists.txt - и тут вроде синтаксис что видишь, то и значит, но понять, так где править, слишком сложно, т.к. каждый по-другому реализует простейшие вещи или напридумывает своих велосипедов. Так что приходится читать весь файл, чтобы разобраться что там от чего зависит. Ну, а о том, сколько он вспомогательных вложенных каталогов и файлов создаёт, я вообще молчу. Если при сборке вдруг что-то пошло не так, трудно найти виноватое место в CMakeLists.txt.

gag ★★★★★
()
Ответ на: комментарий от intelfx

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

Но других же не заставишь иметь да уметь. А вот расхлёбывать самому.

gag ★★★★★
()
Ответ на: комментарий от gag

А ещё регистронезависимость — полное говно.

Открываешь CMakeLists.txt в разных проектах (а то и в одном и том же) и видишь:

TARGET_LINK_LIBRARIES(program mylib)

target_link_libraries(program mylib)

Target_Link_Libraries(program mylib)

Target_link_libraries(program mylib)

Сразу вспоминается DOS, Windows с его

#include <STDAFX.H>
#include <Conio.h>
#include <Iostream.h>

EXL ★★★★★
()
Ответ на: комментарий от EXL

Да, давай, расскажи мне, как CMake должен собрать *.moc-файлы и прилинковать их, если ТС-нуб не осилил прочитать доку на кьют и добавить $MOC_SOURCES в список файлов для компиляции.

Через libastral, не иначе.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 3)
Ответ на: комментарий от intelfx

Я почему-то решил, что у ТС просто демонстрационный пример.

EXL ★★★★★
()
Ответ на: комментарий от intelfx
set_property(TARGET program
APPEND
PROPERTY COMPILE_OPTIONS -Wall -Werror)


А это кстати кроссплатформенно? Мне на тачке с MS Windows -> MSVC оно развернётся в /Wall /WX?

EXL ★★★★★
()

Ну вот мне недавно тут попался проект любителя freebdsm, так вот, там в качестве системы сборки используется GNU make. И хоть проект и кроссплатформенный (с разными бэкендами для разных платформ), мне пришлось копаться в кишочках, удалять кривые зависимости (если линукс, то значит обязательно линкуем pulseaudio и systemd? что?) и править дефайны в исходниках. Да вот же тот проект: http://byuu.org/ ! Явно не хватает cmake.

anonymous
()
Ответ на: комментарий от intelfx

Вот, кстати было бы полезно сделать хотя бы базовые уровни предупреждений кроссплатформенно (без предупреждений/вывод всех предупреждений/предупреждения как ошибки).

Странно, что это не реализовали.

https://cmake.org/Wiki/CMake_Platform_Dependent_Issues#Compiler_Options_and_F...

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)
Ответ на: комментарий от intelfx

А где в доке про $MOC_SOURCES?

в список файлов для компиляции

Ты имеешь ввиду:

set(SOURCES
    src/main.cpp
    src/Util.cpp
    src/Vendor.cpp
    src/ParseCommandLine.cpp
    src/modules/network/Network.cpp
    ...
    ${MOC_SOURCES}
)

?

EXL ★★★★★
()

Тот случай, когда система сборки более упорота, чем язык.

Даже в qbs меньше писанины, а он не заточен только под плюсы, в отличии от.

RazrFalcon ★★★★★
()
Ответ на: комментарий от EXL

Или так, или свойство цели AUTOMOC + добавить хедеры в исходники.

intelfx ★★★★★
()

Мне тоже не понравился. И документация хуже автотулзов.

mv ★★★★★
()
Ответ на: комментарий от EXL

Наверное, потому что тогда начались бы вопли вида «Ой, а почему параметры для моего $говна_мамонта не поддерживаются, ололо, цмейк не кроссплатформенный». К тому же в разных компиляторах бывают совсем разные флаги, не отображаемые друг на друга.

Поэтому единственное рабочее решение — это вручную выбрать проставить нужные флаги для всех компиляторов, совместимость с которыми тебя заботит, (т. е. если без этих флагов проект, например, не соберётся).

А остальные флаги-примочки (варнинги, уровень оптимизации, etc.) стоит указывать при сборке в зависимости от задач и потребностей, и уж точно не перечислять по дефолту в скрипте сборки.

intelfx ★★★★★
()
Ответ на: комментарий от Harald

В надёжных и проверенных временем автотулзах не смогли разобраться сопровождающие пакета, программу в котором автор давно забросил. Так что они просто выбросили пакет из дистрибутива, так как он не собирался с новыми версиями Boost.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

понаберут сопровождающих по объявлениям, которые свои прямые обязанности не осиливают :) автотулзы не виноваты

Harald ★★★★★
()
Ответ на: комментарий от Harald

автотулзы не виноваты

Как и остальные системы, какими бы маргинальными они не были. В итоге всё сводится к поиску людей, способных решить проблему. Для скрипта, который автор даже не сам писал, скорее всего, специалистов не нашлось. А в CMake «из коробки» есть поддержка Boost; такого бы не произошло.

i-rinat ★★★★★
()
Ответ на: комментарий от EXL

Наверное, потому что тогда начались бы вопли вида «Ой, а почему параметры для моего $говна_мамонта не поддерживаются, ололо, цмейк не кроссплатформенный». К тому же в разных компиляторах бывают совсем разные флаги, не отображаемые друг на друга.

Поэтому единственное рабочее решение — это вручную выбрать проставить нужные флаги для всех компиляторов, совместимость с которыми тебя заботит, (т. е. если без этих флагов проект, например, не соберётся).

А остальные флаги-примочки (варнинги, уровень оптимизации, etc.) стоит указывать при сборке в зависимости от задач и потребностей, и уж точно не перечислять по дефолту в скрипте сборки.

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

Поэтому единственное рабочее решение — это вручную выбрать проставить нужные флаги для всех компиляторов, совместимость с которыми тебя заботит, (т. е. если без этих флагов проект, например, не соберётся).

...и после этого выбросить CMake, поскольку он уже не нужен.

tailgunner ★★★★★
()
Ответ на: комментарий от intelfx

А остальные флаги-примочки (варнинги, уровень оптимизации, etc.) стоит указывать при сборке в зависимости от задач и потребностей, и уж точно не перечислять по дефолту в скрипте сборки.

Печально что для многих товарищей это неочевидно, и получается треш типа такого https://github.com/awesomeWM/awesome/issues/953. Есть мнение что таким в основном страдают виндузятники и проприетарщики, и у тех и у других upstream и downstream одно и тоже, обколются своей марихуаной и хардкодят флаги.

А если ещё и всякие виндовенькие костыли типа CMAKE_BUILD_TYPE начинают энфорсить, вообще хоть стой хоть падай.

d_a ★★★★★
()
Последнее исправление: d_a (всего исправлений: 1)
Ответ на: комментарий от Harald

Официальная документация большая и сложная. Я думаю, лучше давать ссылку на Autotools Mythbuster. А вообще в данном случае используется кастрированная IDE и проблема больше в ней.

xaizek ★★★★★
()
Ответ на: комментарий от Harald

Если юниксвеем ты называешь адский костыль без обратной и будущей совместимости с самим собой, который генерирует тормозные скрипты на шелле размером в сотни тысяч строк, которые проверяют параметры, не менявшиеся со времён царя гороха, то ок.

И это я ещё не упомянул про m4.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Я не ТС, но тоже скажу спасибо.

Почему-то твои примеры по cmake выглядят намного более красивыми, чем то, что я обычно вижу в чужом CMakeLists.txt...

hobbit ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.