Идеальный Makefile - PullRequest
       8

Идеальный Makefile

5 голосов
/ 07 августа 2009

Я бы хотел использовать make для получения модульной сборки в сочетании с непрерывной интеграцией , автоматическим модульным тестированием и многоплатформенных сборок . Подобные настройки распространены в Java и .NET, но мне сложно собрать их вместе для make и C / C ++. Как этого добиться?

Мои требования:

  • быстрая сборка; нерекурсивный make (вопрос переполнения стека Каков ваш опыт работы с нерекурсивным make? )
  • модульная система (то есть минимальные зависимости, make-файл в подкаталоге с компонентами)
  • мультиплатформенный (обычно ПК для модульного тестирования, встроенная цель для интеграции / выпуска системы)
  • полная проверка зависимостей
  • способность выполнять (автоматические) модульные тесты (Agile engineering)
  • подключиться к системе непрерывной интеграции
  • простой в использовании

Я начал с non-rec make . Я все еще нахожу это отличным местом для начала.

Ограничения на данный момент:

  • нет интеграции модульных тестов
  • несовместимость компиляторов ARM на базе Windows с путями Cygwin
  • несовместимость make-файла с Windows \ paths
  • прямые зависимости

Моя структура выглядит так:

    project_root
       /algorithm
                 /src
                     /algo1.c
                     /algo2.c
                 /unit_test
                     /algo1_test.c
                     /algo2_test.c
                 /out
                     algo1_test.exe
                     algo1_test.xml
                     algo2_test.exe
                     algo2_test.xml
             headers.h
       /embunit
       /harnass
   makefile
   Rules.top

Я бы хотел, чтобы все было просто; здесь модульные тесты (algo1_test.exe) зависят как от компонента «алгоритм» (хорошо), так и от структуры модульного теста (которая может быть или не быть известной во время ее создания). Однако перемещение правил сборки в топ-макет меня не привлекает, так как это распространит локальные знания о компонентах по всей системе.

Что касается путей Cygwin: я работаю над сборкой, используя относительные пути. Это решает проблему /cygdrive/c (поскольку компиляторы обычно могут обрабатывать / пути) без добавления C: (что не нравится). Есть другие идеи?

Ответы [ 2 ]

3 голосов
/ 25 августа 2009

CMake вместе со связанными инструментами CTest и CDash, кажется, отвечают вашим требованиям. Стоит посмотреть.

Билл Хоффман (ведущий разработчик CMake) ссылается на рекурсивную марку, считающуюся вредной в статье в списке рассылки CMake:

... так как cmake создает make-файлы для вас, многие из недостатков избегать рекурсивного make, например, вам не нужно отлаживать make-файлы или даже думать о том, как они работают. Есть и другие примеры вещей в этой статье, которые cmake исправит и для вас.

См. Также этот ответ для "Рекурсивное создание - друг или враг?" здесь на стеке потока.

- Рекурсивный маркер - друг или враг?

0 голосов
/ 15 августа 2012

Хорошо, вот что я делаю:

Я использую один Makefile в корневом каталоге и шаблоны подстановочных знаков для сбора всех файлов в каталоге. Обратите внимание, что я предполагаю, что foo / *. C будет составлять, например, foo.so. Это делает обслуживание Makefile минимальным, поскольку простое добавление файла в каталог автоматически добавляет его в сборку.

Поскольку это make, который вы используете, я предполагаю (я делаю это для моих проектов), что используется компилятор, использующий синтаксис командной строки, совместимый с gcc (cc). Так что MSC вышел из строя; но не расстраивайтесь, я делаю большую часть своей разработки (к сожалению) для Windows и использую MinGW с MSys; работает как шарм. Создает собственные двоичные файлы, но был собран с помощью среды сборки, совместимой с Posix.

Проверка зависимостей выполняется с помощью стандартного переключателя -MD. Затем я включаю все файлы * .d в Makefile. Я строю шаблоны из автоматически собранных исходных файлов.

Наконец, модульные тесты реализованы с «стандартной» целью check. Цель проверки похожа на цель цели, за исключением того, что она зависит от модульного теста и выполняется после того, как все построено. Я делаю это так, чтобы вы могли раздельно построить проект или построить модульные тесты (и остальную часть проекта). Когда я не занимаюсь разработкой проекта, я хочу просто создать его и покончить с ним.

Вот пример того, как я это делаю: https://github.com/rioki/c9y/blob/master/Makefile У него также есть цели install, uninstall и dist.

Как вы можете видеть, все делается просто, никаких рекурсивных вызовов и все относительно просто. Я использовал automake и autoconf, и я никогда не буду делать это снова; о других инструментах сборки не может быть и речи, если мне нужно установить foojam или barmake для сборки чего-либо, я обычно немедленно отказываюсь от этого проекта.

...