Makefile. Компиляция нескольких файлов с исходным кодом

Поделиться
HTML-код
  • Опубликовано: 16 июн 2021
  • Как устроен Makefile? Как скомпилировать проект из нескольких исходников? Как составить универсальный Makefile для компиляции проекта с любым количеством исходников? Как распределить по разным папкам исходники и объектные файлы? На все эти вопросы есть ответы в данном видео.

Комментарии • 72

  • @Ocak-ok1li
    @Ocak-ok1li 19 дней назад

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

  • @musaseyd9353
    @musaseyd9353 2 года назад +5

    спасибо большое, спустя столько попыток разобраться, мне наконец-то стало понятно

  • @SRoach
    @SRoach 10 месяцев назад +2

    Большое спасибо за видео. Весьма полезно и интересно!

  • @zoompartyru
    @zoompartyru 2 месяца назад +1

    Отличная подача материала. Спасибо !

  • @rakydze3408
    @rakydze3408 2 года назад +4

    Всё доходчиво чтобы понимали такие как я =) Отлично. Спасибо.

  • @user-bh8xz4xy7o
    @user-bh8xz4xy7o Год назад +5

    Господи, почему же я не нашёл это видео раньше, автору гигантское спасибо!!!

  • @user-ji4ic6tp9u
    @user-ji4ic6tp9u Год назад +13

    Приятная подача материала с хорошей методической проработкой. Молодец!

  • @native-nature-video
    @native-nature-video 7 месяцев назад

    Отличный туториал. Спасибо!!!

  • @Notthetylor
    @Notthetylor Год назад +4

    Thanks a lot bro... U searched many things but only ur content was in high quality . Lucky me that I know Russian)))

  • @user-mp9cp7ej5f
    @user-mp9cp7ej5f 6 месяцев назад

    Спасибо! Очень хорошее объяснение!

  • @kamosevoyan4370
    @kamosevoyan4370 2 года назад +1

    Спасибо большое приятель.

  • @olegkhotin4077
    @olegkhotin4077 9 месяцев назад

    Божественный контент!

  • @janerobertson5628
    @janerobertson5628 5 месяцев назад

    Здравствуйте, огромный вам спасибо за ценный урок!

  • @ruslanakhmetzyanov5503
    @ruslanakhmetzyanov5503 3 месяца назад

    Лучшее видео, благодарю

  • @yodapunishes
    @yodapunishes Год назад

    Спасибо, супер объяснение

  • @YevheniiSerdiukov
    @YevheniiSerdiukov 2 года назад

    Спасибо большое дружище !

  • @IllidanZur
    @IllidanZur 8 месяцев назад

    отличное видео большое спасибо

  • @hwd1978
    @hwd1978 8 месяцев назад

    Круто! Спасибо!

  • @7dtd_ruplay306
    @7dtd_ruplay306 Год назад

    Отличное видео!

  • @p.polunin
    @p.polunin Год назад

    Спасибо

  • @user-qy8dg4rm8i
    @user-qy8dg4rm8i Год назад

    Cпасибо!

  • @artemherich8203
    @artemherich8203 2 года назад

    Браво

  • @eudziro
    @eudziro 5 месяцев назад

    Круто! Спасибо, очень помогли! Кстати голос похож на shimoroshow

  • @1111ilya
    @1111ilya Год назад

    крутяк чел!

  • @user-bt2ex4zw3v
    @user-bt2ex4zw3v Год назад

    Огромное спасибо то что нужно было!)

  • @hwd1978
    @hwd1978 8 месяцев назад +1

    Ещё раз спасибо! А как решать проблему отслеживания изменений заголовочных файлов? И ещё вопрос: ведь в каталоге src исходник могут быть размещены по подкаталогам произвольной структуры. Как этот момент учесть?

    • @tripledistillation1755
      @tripledistillation1755  7 месяцев назад

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

    • @andrewkruchini8614
      @andrewkruchini8614 7 месяцев назад

      @@tripledistillation1755 например, в Вашем примере не указаны зависимости от my_lib.h

    • @tripledistillation1755
      @tripledistillation1755  Месяц назад

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

  • @yurapetrovski3927
    @yurapetrovski3927 10 месяцев назад

    супер, спасибо большое, а планируется ли видео про cmake или юнит тесты?

    • @tripledistillation1755
      @tripledistillation1755  10 месяцев назад +4

      Этого в планах нет. Была задача сформировать такой makefile, чтобы потом про него забыть и никогда не вспоминать, но чтобы при копировании в папку с новым проектом все .c файлы компилировались и собирались в исполняемый файл.
      Может эта тема и заинетесует, но многообразие утилит для сборки и тестирования пока что только огорчает, так как попытки собрать проект из исходников напоминют ситуацию, когда ты заказал табурет, и мастер уже забивает последний гвоздь и вдруг говорит: "для двух последних ударов нужен молоток Х". Отвечаешь: "у меня такого нет, но есть Y и он вполне способен решить эту задачу". А мастер в ответ выдергивает гвоздь, разламывает всю табуретку и уходит. Стоит тебе через время найти этот X, как мастер заявлает, что тот уже старый и нужен "X 5.0", и вообще, половина досок уже "deprecated"

  • @user-bv9ch8wj9r
    @user-bv9ch8wj9r Год назад +2

    САЛАМАЛЕЙКУМ МИФИСТЫ

  • @nnkakoito4699
    @nnkakoito4699 2 года назад +2

    А если у меня в src лежат несколько папок, и все файлы в этих папках надо скомпилировать, но так-же есть и файлы которые не в папках, как можно это сделать?

    • @tripledistillation1755
      @tripledistillation1755  2 года назад +9

      TARGET = MyProject
      CC = gcc
      PREF_SRC = ./src/
      PREF_OBJ = ./obj/
      SRC = $(shell find . -name "*.c")
      OBJ = $(patsubst $(PREF_SRC)%.c, $(PREF_OBJ)%.o, $(SRC))
      $(TARGET) : $(OBJ)
      $(CC) $(OBJ) -o $(TARGET)
      $(PREF_OBJ)%.o : $(PREF_SRC)%.c
      mkdir -p $(dir $@)
      $(CC) -c $< -o $@
      clean :
      rm $(TARGET) $(OBJ)
      Разница в том, что в переменой SRC список всех файлов, оканчивающихся на ".c", в том числе и в подкатологах внутри src. Команда shell позволяет выполнить команду оболочки и получить результат в виде строки. Далее заменяем префикс "./src/" на "./obj/", а так же расширение ".c" на ".o" с помощью команды patsubst во всех найденных именах файлов исходников. Таким образом, структура папок внутри "./obj/" предполагается такой же, как и в "./src/", но компилятор не будет создавать недостающие папки автоматически по относительному пути файла в "./obj/". Чтобы решить эту проблему, в правило компиляции отдельного исходника добавлена команда mkdir -p $(dir $@). Здесь $@ - это имя файла-цели, то есть файла ".o". dir позволяет выделить из этого имени имя католога, а ключ -p блокирует ошибку, если католог уже существует.

  • @mirvin11
    @mirvin11 Год назад +2

    Не понимаю в чём глобальная разница от bash скриптов

  • @userqh67vey6
    @userqh67vey6 8 месяцев назад

    Зачем городить огород с мейкфайлом, если можно зависимости прописать в include в исходниах => тогда чтобы собрать проект, нужно скомпилировать 1 файл c main(), а все остальные подтянутся автоматически?

    • @vitlevanskiy
      @vitlevanskiy 8 месяцев назад

      Тогда огородом будет main(), из за каждого там изменения все инклюды компилируй по 100 раз. Может откомпилировать их и больше не трогать никогда?

    • @userqh67vey6
      @userqh67vey6 8 месяцев назад

      @@vitlevanskiy зависит от IDE. Visual studio сама умеет находить .c файлы по имени h файла в правильной папке и повторно не компилирует если нет изменений.

  • @10Dima01
    @10Dima01 Год назад +3

    Кажется, что после распределения файлов (.с и .о) по папкам необходимо слегка модифицировать clean цель.

    • @tripledistillation1755
      @tripledistillation1755  Год назад

      Предлагайте свой вариант, будет интересно

  • @Buterbrodsgribami
    @Buterbrodsgribami 2 года назад +1

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

    • @tripledistillation1755
      @tripledistillation1755  2 года назад +1

      Можно. Если вопрос касается материала или чего-то смежного, то задавайте его здесь

  • @daniilgavr5811
    @daniilgavr5811 Год назад +1

    Кажется, стоило бы .h тоже добавить в зависимости

    • @tripledistillation1755
      @tripledistillation1755  Год назад

      Возможно. Но gcc компонует исполняемый файл из набора модулей (.o), поэтому они присутствуют в зависимостях. Получение файлов (.o) - это тоже набор целей Makefile-а, для достижения которых нужны соответствующие исходники (.c). А вот какие заголовочные файлы использовать для компиляции исходников, указано в самих исходниках

    • @daniilgavr5811
      @daniilgavr5811 Год назад +3

      @@tripledistillation1755 Да, но вот если в проекте поменять .h, но не менять ничего другого - модули не перекомпилируются

  • @user-yg8yp8kx5e
    @user-yg8yp8kx5e Месяц назад

    Хороший гайд. Но не все вопросы решены. Что делать, если в проекте есть код на нескольких языках? А ещё проект состоит из десятка других проектов, и вообще не ясно, что где лежит. У кого-то cmake прикручен, у кого-то makefile, а некоторые вообще sln. И ещё некоторые любят писать #include , а кто-то просто пишет #include , кто-то #include "C:\васян\sdl. h" , и плевать они хотели на то, что это один файл. Кому-то так удобнее, кому-то так. А тебе все это читать и переписывать не надо, тебе бы только скомпилировать. Под виндой кто-то уже для всего этого цирка сделал sln, и это работает. А makefile нет. Конкретно в моём случае это ещё и статическая библиотека name.lib, которую надо бы пересобрать для линукса в name.a. Если будет настолько обширный гайд, то тема уже будет освещена полностью

    • @tripledistillation1755
      @tripledistillation1755  Месяц назад

      Да, есть над чем подумать. Для заголовочных файлов можно добавить место поиска с помощью опции -I. Makefile очень часто бывает результатом работы скрипта "configure" в случае Linux. Поэтому имеет смысл этот скрипт разобрать. Ещё подкинули вопрос насчет изменения содержимого .h файлов - мол, нужно добавить зависимость. Тут гайд скорее ситуационный: мне нужно было решить конкретную задачу - вот решил до определенной степени и поделился)

  • @user-ol2zz5hq5l
    @user-ol2zz5hq5l 3 месяца назад

    А если используется header файл?

    • @tripledistillation1755
      @tripledistillation1755  3 месяца назад

      Приведите конкретный пример

    • @user-ol2zz5hq5l
      @user-ol2zz5hq5l 3 месяца назад

      @@tripledistillation1755 , прошу прощения. Например для создания библиотеки, мы используем .h, и если изменить этот хедер файл, то нужно будет пересобирать все .c файлы, зависимые от него. Спасибо за видео!

    • @tripledistillation1755
      @tripledistillation1755  3 месяца назад

      Верно. Спасибо за комментарий

  • @MECHANISMUS
    @MECHANISMUS Год назад

    $(PREF_OBJ)%.c: $(PREF_SRC)%.o тут уже лишнее. Переменные SRC и OBJ уже содержат префы. То есть $(OBJ): $(SRC). Для этого ж они и создавались.

    • @tripledistillation1755
      @tripledistillation1755  Год назад +1

      Если вместо " $(PREF_OBJ)%.o: $(PREF_SRC)%.c " использовать " $(OBJ): $(SRC) ", то Make может неправильно сопоставить имена исходников и объектных файлов. Таким образом, при компиляции main.c объектный код может быть отправлен в my_lib.obj, например.

    • @MECHANISMUS
      @MECHANISMUS Год назад

      @@tripledistillation1755 я попытался подставить готовые списки. Мэйк безошибочно перебирает список зависимостей по порядку, но почему-то подставляет в каждой команде только первое значение из списка целей (адресовал через $^). При подстановке корня то же правило работает чётко. Видимо, только так.

    • @tripledistillation1755
      @tripledistillation1755  Год назад

      @@MECHANISMUS да, я столкнулся с такой же проблемой, пытаясь проверить предложенный Вами вариант. Спасибо за обратную связь и рассмотренный случай

    • @user-dk6ii3iz4o
      @user-dk6ii3iz4o Год назад

      @@MECHANISMUS у меня тоже самое, только верно перебирает список целей и в каждой команде подставляет первый аргумент из зависимостей. Как решить понятия не имею. Метод из видео выдает ошибку, что нет правила для сборки объектников, хотя указано все точно так же.

  • @sergkornev2811
    @sergkornev2811 2 года назад +17

    спасибо ничего не работает

    • @comachine
      @comachine Год назад +6

      @You Tube если не получается забить гвоздь молотком, это еще не значит, что молоток плохой)))

  • @user-ei8vt4pt2r
    @user-ei8vt4pt2r 6 месяцев назад

    делайте, пожалуйста, крупнее: на телефоне не разглядеть

    • @tripledistillation1755
      @tripledistillation1755  2 месяца назад

      Тут видео в принципе не рассчитано на такой способ просмотра, но подумаю

  • @saidamir6538
    @saidamir6538 6 месяцев назад

    Вы из стс? На голос из галилео похож

  • @reklats7270
    @reklats7270 Год назад

    А если у меня один cpp и один h файл?

    • @tripledistillation1755
      @tripledistillation1755  Год назад

      Можно поместить их в "src", а в Makefile-е заменить все вхождения ".c" на ".cpp"

  • @shluhogon_42
    @shluhogon_42 Год назад

    ох уж эти гайды, когда все лежит в одной папке

  • @McGewen
    @McGewen Год назад +1

    ЛИЧНО РУКУ ПОЖАЛ БЫ!!!!!!!!!!!!!!!!!

  • @nRADRUS
    @nRADRUS 8 месяцев назад

    Makefile в целом достаточно бесполезен. Всё равно многие тулзы не создают файлов для зависимостей, поэтому можно просто sh-скрипт писать, и компилировать просто всё заново. Для малых проектов в винде это windres, крупные проекты так вообще свои тулзы имеют, как тот же firefox.

  • @daniilk4994
    @daniilk4994 10 месяцев назад

    А почему бы не написать баш скрипт? В чем разница? Зачем мне именно make?

    • @tripledistillation1755
      @tripledistillation1755  10 месяцев назад +1

      В том, что в make есть механизм
      " :
      "
      А это удобно в случае сборки проекта. Можно относительно просто выстроить дерево зависимостей. Такая задача наверняка решаема в bash, но, может быть, с большими усилиями. Но это то, как я себе представляю ситуацию. А вообще, make - это утилита, то есть средство, а не цель. Средства могут быть разными, зацикливаться на них не следует

    • @daniilk4994
      @daniilk4994 10 месяцев назад

      @@tripledistillation1755 да, досмотрел видос до конца, немного поюзал, удобнее, чем могло бы быть с башем)