Вопрос гуру make – как организовать правильно (так что би через 20 лет было не стыдно) make файл для следующего:
Есть три проекта с++. Все они лежат в общей папочке. Один из проектов как бы главный и использует остальные два. Остальные два могут собираться в своих папочках в основном для исполнения UNIT тестов. Однако главная цель таки собрать основной проект для 32 и 64 платформ. Вопрос как лучше поступить — сделать основной Makefile в общей папочке и держать в каждой подпапочке свой Makefile и основной Makefile просто будет инклюдить все остальные и можно ожидать что они будут последовательно исполнятся. Хотя как я понял цель all может быть только одна и если мы инклюдим в один файл три других то будет ругань со стороны make что мол цель all должна быть одна.
Либо сделать общий для всех проектов Makefile там определить цель all и в одном файле прописывать все зависимости. В этом случае у нас проект получается жесткой структуры – все завсит от одного файла, страдает модульнось.
Посоветуйте как сделать именно правильно. Что бы бабушка гордилась
Еще вдогонку — проект должен быть под 32 и 64 — как лучше поступить — сделать специальную цель для скажем 32 если я ожидаю, что большинство будет строить под 64 или держать два Makefile каждый для своей платформы в отдельных подпапках или как? Или скрипты специальные строительные сделать...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Используй CMake, и лёгким движением руки у тебя появятся и проекты Visual Studio, и Eclipse, и QT Creator, и Unix Makefiles.
Здравствуйте, LowCoder, Вы писали:
LC>Или скрипты специальные строительные сделать...
Взять cmake и использовать его. Можно написать makefile, который будет вызывать cmake который будет генерить nakefile-ы для проектов.
Здравствуйте, LowCoder, Вы писали:
LC>Вопрос гуру make – как организовать правильно (так что би через 20 лет было не стыдно) make файл для следующего: LC>Есть три проекта с++. Все они лежат в общей папочке. Один из проектов как бы главный и использует остальные два. Остальные два могут собираться в своих папочках в основном для исполнения UNIT тестов. Однако главная цель таки собрать основной проект для 32 и 64 платформ. Вопрос как лучше поступить — сделать основной Makefile в общей папочке и держать в каждой подпапочке свой Makefile и основной Makefile просто будет инклюдить все остальные и можно ожидать что они будут последовательно исполнятся. Хотя как я понял цель all может быть только одна и если мы инклюдим в один файл три других то будет ругань со стороны make что мол цель all должна быть одна.
LC>Либо сделать общий для всех проектов Makefile там определить цель all и в одном файле прописывать все зависимости. В этом случае у нас проект получается жесткой структуры – все завсит от одного файла, страдает модульнось.
LC>Посоветуйте как сделать именно правильно. Что бы бабушка гордилась LC>Еще вдогонку — проект должен быть под 32 и 64 — как лучше поступить — сделать специальную цель для скажем 32 если я ожидаю, что большинство будет строить под 64 или держать два Makefile каждый для своей платформы в отдельных подпапках или как? Или скрипты специальные строительные сделать...
Прежде всего, all должна строить действительно all: все три проекта, в вариантах 32, 64, debug и release. В скобках: никто не обязывает называть дефолтную цель именно так.
Во-вторых, разница между монолитным мейкфайлом и подключаемыми фрагментами достаточно тонка; особенно с точки зрения модульности. При трех тесно связаных проектах я бы с дроблением не заморачивался.
В-третьих, никакого смысла в отдельных мейкфайлах для 32 и 64 нет.
PS: если сможете описать структуру проектов поподробнее, помощь будет поконкретнее.
Здравствуйте, LowCoder, Вы писали:
LC>Вопрос гуру make – как организовать правильно (так что би через 20 лет было не стыдно) make файл для следующего: LC>Вопрос как лучше поступить — сделать основной Makefile в общей папочке и держать в каждой подпапочке свой Makefile и основной Makefile просто будет инклюдить все остальные и можно ожидать что они будут последовательно исполнятся.
Если ты под "инклудить" ты понимаешь директиву include, то именно так и надо делать.
Исполняться будет параллельно, будет общий граф зависимостей и билд будет происходить наиболее оптимальным образом.
Про all уже сказали — юзай .DEFAULT_GOAL
LC>Еще вдогонку — проект должен быть под 32 и 64 — как лучше поступить — сделать специальную цель для скажем 32 если я ожидаю, что большинство будет строить под 64 или держать два Makefile каждый для своей платформы в отдельных подпапках или как? Или скрипты специальные строительные сделать...
Я это делаю через переменную окружения
Типа "make arch=32"
Здравствуйте, LowCoder, Вы писали:
LC>Либо сделать общий для всех проектов Makefile там определить цель all и в одном файле прописывать все зависимости. В этом случае у нас проект получается жесткой структуры – все завсит от одного файла, страдает модульнось.
Я не гуру. Делаю так:
В подпапках свои файлы.
В корневом файле трансляция целей вида:
SUBDIRS= sub1 \
<------> sub2 \
default:
<------>for p in $(SUBDIRS); do (cd $$p; make $@; cd ..;); done
all:
<------>for p in $(SUBDIRS); do (cd $$p; make all; cd ..;); done
А инклюды только для типовых действий (в результате файлы в подпапках минимальные)
Здравствуйте, pivcorp, Вы писали:
P>Здравствуйте, LowCoder, Вы писали:
LC>>Либо сделать общий для всех проектов Makefile там определить цель all и в одном файле прописывать все зависимости. В этом случае у нас проект получается жесткой структуры – все завсит от одного файла, страдает модульнось.
P>Я не гуру. Делаю так: P>В подпапках свои файлы. P>В корневом файле трансляция целей вида:
P>
P>all:
P><------>for p in $(SUBDIRS); do (cd $$p; make all; cd ..;); done
P>
$(MAKE) -C $$p несколько кошернее. Но вообще-то рекурсивный make не рекомендуется (статья старая, но все еще актуальная).
Мне нравится как устроен boost build. Существует уже много лет, работает для множества связанных друг с другом библиотек. Кажется может быть хорошим ориентиром, судя по постановке вопроса.
P>SUBDIRS= sub1 \
P><------> sub2 \
P>default:
P><------>for p in $(SUBDIRS); do (cd $$p; make $@; cd ..;); done
P>all:
P><------>for p in $(SUBDIRS); do (cd $$p; make all; cd ..;); done
P>
так все обычно и делают — рекурсивеый make называется. хуже чем goto
вот некоторые причины, почему это плохо:
— толком не отследить зависимости. например, если sub1 зависит от sub2, то уже имеем проблемы
— паралельный make (-j 2) не будет работать на более-менее сложном проекте. кстати, отличный стресс тест для билд-системы — запустить make с ключем -j 2 или больше.
— рекурсивный make работает гораздо медленнее. потому что каждый для каждого подкаталога надо стартовать процесс make, он должен прочитать ваши мейкфайлы. причем одни и те же файлы, в которых у вас общие настроки проекта, будут читаться много-много раз. тормоза в глаза бросаются особенно под cygwin-ом.
вообщем, если проект простой, то можно и так. но лучше сразу делать нормально. только это непросто, потому что make примитивнен.
Здравствуйте, LowCoder, Вы писали:
LC>Вопрос гуру make – как организовать правильно (так что би через 20 лет было не стыдно) make файл для следующего: LC>Есть три проекта с++. Все они лежат в общей папочке. Один из проектов как бы главный и использует остальные два. Остальные два могут собираться в своих папочках в основном для исполнения UNIT тестов. Однако главная цель таки собрать основной проект для 32 и 64 платформ. Вопрос как лучше поступить — сделать основной Makefile в общей папочке и держать в каждой подпапочке свой Makefile и основной Makefile просто будет инклюдить все остальные
LC>и можно ожидать что они будут последовательно исполнятся.
makefile-ы не императивные, а декларативные: ты описываешь цели, их взаимозависимости и правила построения. make на основе этой информации строит дерево зависимостей и сам решает, что и когда строить/исполнять.
LC>Хотя как я понял цель all может быть только одна и если мы инклюдим в один файл три других то будет ругань со стороны make что мол цель all должна быть одна.
цель одна, а правил для ее постройки может быть несколько:
LC>Посоветуйте как сделать именно правильно. Что бы бабушка гордилась
судя по заданным вопросам и предположениям, предметом ты владеешь слабо. так что с первого раза получится плохо в любом случае