diff options
author | Sergey Nazaryev <sergey@nazaryev.ru> | 2016-06-05 03:01:51 +0000 |
---|---|---|
committer | Sergey Nazaryev <sergey@nazaryev.ru> | 2016-06-05 03:01:51 +0000 |
commit | 877cfec696e38b2af326d86009fbe3fd450ad727 (patch) | |
tree | f33f4d0f6c23cf1f9b470dde3faa278d3b3266eb | |
download | itiviti-aptitude-test-877cfec696e38b2af326d86009fbe3fd450ad727.zip itiviti-aptitude-test-877cfec696e38b2af326d86009fbe3fd450ad727.tar.gz itiviti-aptitude-test-877cfec696e38b2af326d86009fbe3fd450ad727.tar.bz2 |
Initial release
-rw-r--r-- | Makefile.inc | 20 | ||||
-rw-r--r-- | PROBLEM | 70 | ||||
-rw-r--r-- | README | 48 | ||||
-rw-r--r-- | README.md | 5 | ||||
-rwxr-xr-x | build-system-shell | 11 | ||||
-rw-r--r-- | src/libraries/storage/Makefile | 4 | ||||
-rw-r--r-- | src/libraries/transport/Makefile | 5 | ||||
-rw-r--r-- | src/libraries/util/Makefile | 5 | ||||
-rw-r--r-- | src/servers/Makefile | 3 | ||||
-rw-r--r-- | src/servers/trading/fix/Makefile | 5 |
10 files changed, 176 insertions, 0 deletions
diff --git a/Makefile.inc b/Makefile.inc new file mode 100644 index 0000000..5e8ac8e --- /dev/null +++ b/Makefile.inc @@ -0,0 +1,20 @@ +# TODO: MAKEFILE_LIST может хранить больше, чем один (наш) Makefile, в +# зависимости от переменной окружения MAKEFILES +buildsysdir = $(strip $(dir $(firstword $(MAKEFILE_LIST)))) +projectdir = $(CURDIR:$(buildsysdir)%=%) + +build: + @[ "$(DRIVER)" == "subdir" ] && echo "Building $(DRIVER) $(projectdir)"; + @builtlist="$(BUILTLIST)"; \ + deps=''; \ + for i in $(DEPENDS) $(SUBDIRS); do \ + if [[ ":$$builtlist:" != *":$$i:"* ]]; then \ + deps=$$(make BUILTLIST="$$builtlist" -C "$(buildsysdir)$$i" 3>&1 1>&2); \ + builtlist="$$builtlist:$$deps"; \ + echo "$$i" >&3; \ + fi \ + done; + @[ "$(DRIVER)" == "executable" || "$(DRIVER)" == "dynamic-library" ] && echo "Building $(DRIVER) $(projectdir)" >&2 + @echo "$(projectdir)" >&3 + +# vim: set ft=make: @@ -0,0 +1,70 @@ +Тестовое задание Itiviti +======================== + +Реализовать рекурсивный обход дерева проектов на GNU make. + +Есть иерархически организованное дерево проектов: + +src/ + libraries/ + storage/ + transport/ + util/ + servers/ + trading/ + fix/ + market_data/ + fix/ + +В каждой директории есть Makefile, описывающий сборку данного проекта, например + +src/servers/trading/fix/Makefile: +------- +NAME = trading_fix +DRIVER = executable +DEPENDS = src/libraries/storage src/libraries/transport +------- + +или + +src/libraries/transport/Makefile: +------ +NAME = transport +DRIVER = dynamic-library +DEPENDS = src/libraries/util +------- + +или + +src/servers/Makefile: +------ +NAME = servers +DRIVER = subdir +SUBDIRS = trading market_data +------ + +Т.е. указывается имя собираемого проекта (NAME), как его собирать (DRIVER) и список зависимостей (DEPENDS). +Для DRIVER=subdir в переменной SUBDIRS перечисляются подпроекты. + +"Рекурсивная" сборка включает в себя сборку всех зависимостей проекта (подпроектов для DRIVER=subdir). + +Например, сборка src/servers/trading/fix вызовет сборку следующих проектов: +src/libraries/util +src/libraries/transport +src/libraries/storage +src/servers/trading/fix + +Задача: написать рекурсивный обход дерева проектов на языке GNU make. + +Т.е. запуск + +$ make -C src/servers/trading/fix + +должен вывести нечто вроде + +Building dynamic-library src/libraries/util +Building dynamic-library src/libraries/transport +Building dynamic-library src/libraries/storage +Building executable src/servers/trading/fix + +Каждый проект при этом должен собираться не более одного раза. @@ -0,0 +1,48 @@ +Тестовая система сборки +======================= + +Эта система сборки позволяет рекурсивно обходить дерево зависимостей, +описанного с помощью файловой системы и метаинформации в Makefile'ах. +Формат метаинформации и более подробную информацию см. в задании (файл +`PROBLEM`). + +Требования к работе системы сборки +---------------------------------- + + * GNU Make + * bash (используется башизм) + +Как использовать +---------------- + +$ ./build-system-shell # войти в shell для сборки +$ make -C src/servers/trading/fix # собрать `src/servers/trading/fix` +$ exit # выйти из shell для сборки + +Как работает +------------ + +Для корректной работы системы необходимо войти в специальный shell. +На самом деле это bash с небольшими изменениями: + * 3 файловый дескриптор проброшен в /dev/null + * во все Makefile'ы, собираемые в этом shell'е, будет + инджектиться Makefile.inc, который предоставляет основной механизм сборки + (переменная `MAKEFILES`). + * отключается лишний verbose от GNU Make (переменная `MAKEFLAGS`) + +После вызова `make -C %проект%` происходит следующее: + * начинает выполняться цель `build` (от неё зависит цель `all` в каждом из `Makefile`) + * перед началом сборки мы проходимся по списку зависимостей и вызываем для + каждой зависимости её Makefile + * после того, как n-ая зависимость собралась, в 3 файловый дескриптор + пишется весь список собранных в процессе её сборки сущностей, который + потом попадает в переменную builtlist + * перед сборкой n-ой зависимости мы смотрим, нет ли уже в переменной + builtlist этой зависимости; если есть -- значит, она уже была собрана в + процессе данной сборки, иначе собираем её. + * в момент каждого дочернего вызова make передаётся переменная BUILTLIST, + содержащая список того, что было собрано родительским и дочерними make'ами + до этого + +*Примечание*: 3 файловый дескриптор нужен для того, чтобы передавать информацию из дочерних +процессов так, чтобы эта информация не перемешивалась с stdout'ом и stderr'ом. diff --git a/README.md b/README.md new file mode 100644 index 0000000..16328df --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +Тестовая система сборки +======================= + + # . build-system.sh + # make -C src/servers/trading/fix diff --git a/build-system-shell b/build-system-shell new file mode 100755 index 0000000..fd906c0 --- /dev/null +++ b/build-system-shell @@ -0,0 +1,11 @@ +#!/bin/bash -efu + +# Переменная DIR содержит путь до директории, которая хранит выполняемый +# скрипт (т.е. этот shell) +# Это нужно для того, чтобы войти в шелл можно было из любой директории и путь +# до Makefile.inc оказался правильным. +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +export MAKEFILES="$DIR/Makefile.inc" +export MAKEFLAGS="--no-print-directory" +exec /bin/bash 3>/dev/null diff --git a/src/libraries/storage/Makefile b/src/libraries/storage/Makefile new file mode 100644 index 0000000..3864c1d --- /dev/null +++ b/src/libraries/storage/Makefile @@ -0,0 +1,4 @@ +NAME = storage +DRIVER = dynamic-library + +all: build diff --git a/src/libraries/transport/Makefile b/src/libraries/transport/Makefile new file mode 100644 index 0000000..78c4519 --- /dev/null +++ b/src/libraries/transport/Makefile @@ -0,0 +1,5 @@ +NAME = transport +DRIVER = dynamic-library +DEPENDS = src/libraries/util + +all: build diff --git a/src/libraries/util/Makefile b/src/libraries/util/Makefile new file mode 100644 index 0000000..46c466c --- /dev/null +++ b/src/libraries/util/Makefile @@ -0,0 +1,5 @@ +NAME = util +DRIVER = dynamic-library +DEPENDS = src/libraries/storage + +all: build diff --git a/src/servers/Makefile b/src/servers/Makefile new file mode 100644 index 0000000..b81b286 --- /dev/null +++ b/src/servers/Makefile @@ -0,0 +1,3 @@ +NAME = servers +DRIVER = subdir +SUBDIRS = trading market_data diff --git a/src/servers/trading/fix/Makefile b/src/servers/trading/fix/Makefile new file mode 100644 index 0000000..9baf9b0 --- /dev/null +++ b/src/servers/trading/fix/Makefile @@ -0,0 +1,5 @@ +NAME = trading_fix +DRIVER = executable +DEPENDS = src/libraries/storage src/libraries/transport + +all: build |