LINUX.ORG.RU

Как указать в Makefile в качестве зависимости - каталог?


1

1

если сделать что-то типа:

all: mydir/mysubdir

mydir/mysubdir:\r\t mkdir -p mydir/mysubdir

(сории, но движок форума прибивает нормальное форматирование.)

НЯМС, если делаешь так, то make считает mydir/mysubdir не названием каталога, а названием цели, в результате он эту цель выполняет всегда, даже если каталог есть. Это приводит к обновлению зависимотей и перелнковке проги.

Вобщем, нужно, чтобы при повторных вызовах make он видел каталоги и понимал что эти зависимости уже есть. Как такое сделать?



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

данный прием - костыль, причем не очень удачный.

Пока сделал так:


createDirs := $(shell test -d $(OBJDIR)||echo create_objs)

myobj.o: myobj.cpp $(createDirs)
     g++ блаблабла

create_objs:
     mkdir ляляля

chabapok
() автор топика
(victor@desktop)~/tmp/ttt $> ls                                                                                             [sh]
Makefile  test.c
(victor@desktop)~/tmp/ttt $> cat Makefile                                                                                   [sh]

all: test example/t 

test: test.o
	gcc -o test test.o

test.o: test.c
	gcc -c test.c

example/t:
	mkdir -p example/t

(victor@desktop)~/tmp/ttt $> where make                                                                                     [sh]
make: aliased to make -j2
/usr/bin/make
(victor@desktop)~/tmp/ttt $> make                                                                                           [sh]
gcc -c test.c
mkdir -p example/t
gcc -o test test.o
(victor@desktop)~/tmp/ttt $> make                                                                                           [sh]
make: Цель `all' не требует выполнения команд.
(victor@desktop)~/tmp/ttt $> make -v                                                                                        [sh]
GNU Make 3.82
Эта программа собрана для x86_64-unknown-linux-gnu
Copyright (C) 2010  Free Software Foundation, Inc.
Лицензия GPLv3+: GNU GPL версии 3 или новее <http://gnu.org/licenses/gpl.html>
Это свободное программное обеспечение: вы можете свободно изменять его и
распространять. НЕТ НИКАКИХ ГАРАНТИЙ вне пределов, допустимых законом.
(victor@desktop)~/tmp/ttt $> ls                                                                                             [sh]
example/  Makefile  test*  test.c  test.o
(victor@desktop)~/tmp/ttt $>                                                                                                [sh]

чяднт

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

данный прием - костыль, причем не очень удачный.

Скажите об этом Ричарду Столлману и Роланду МакГрату - вот они удивятся... я конечно понимаю, что не модно читать руководства, но все же:

GNU Make
====================================================================
                                    Программа управления компиляцией
                                            Редакция 0.48, make 3.73
                                                         Апрель 1995

   Ричард Столлман (Richard M. Stallman)
   Роланд МакГрат (Roland McGrath)

....

 4.6 Пустые целевые файлы для фиксации событий

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

     Предназначение  пустого  целевого  файла - зафиксировать, с помощью
времени  его  последней  модификации,  когда в последний раз исполнялись
команды  из  правила.  Это  делается при помощи включения в набор команд
команды touch для обновления целевого файла.

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

     print: foo.c bar.c
             lpr -p $?
             touch print

Согласно   этому  правилу,  'make  print'  выполнит  команду  lpr,  если
какой-нибудь  исходный  файл  был  изменен  с  момента  последнего 'make
print'.  Автоматическая  переменная  '$?'  используется  для того, чтобы
печатать  только  те  файлы,  которые изменились (смотрите раздел 10.5.3 [Автоматические переменные]).

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

Почему не модно? Очень даже модно. Прежде чем спрашивать, я прочитал вдоль и поперек, и погуглил даже.

А костыль потому, что надо не тупо делать как написано, а понимать для чего это написано и как работает. И уже потом решать является предлагаемое решение удобным для выполнения задачи.

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

К тому же, если быть точным, файл-маркер должен создаваться в каталоге сборки, а не с исходниками. Это по логике вещей. Но ведь каталог сборки может быть еще не создан, mkdir хочется сделать именно такой, чтобы он создал каталог сборки.

вобщем, там выше я привел приемлемое решение..

chabapok
() автор топика

mk подобное умеет делать, странно, что make — нет.

% cat mkfile
all:N: e/foo

e/foo:
    mkdir -p e/foo
% mk
   mkdir -p e/foo
% mk
mk: 'all' is up to date

quantum-troll ★★★★★
()
Ответ на: комментарий от chabapok

А почему у Вас просто указание каталога как цели/зависимости не работает то? У меня вот все работает.

aiv@aivbook:~/tmp$ cat test.mk
a: testdir
        echo 222

testdir:
        echo 111
        mkdir testdir
aiv@aivbook:~/tmp$ make -f test.mk
echo 111
111
mkdir testdir
echo 222
222
aiv@aivbook:~/tmp$ make -f test.mk
echo 222
222
aiv@aivbook:~/tmp$ rm -rf testdir
aiv@aivbook:~/tmp$ make -f test.mk
echo 111
111
mkdir testdir
echo 222
222
aiv@aivbook:~/tmp$

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

Ваш пример заработал, а когда я проверял - не работало. Видимо что-то не так сделал. Ваш пример - самый правильный, спасибо.

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

Хех, возникли новые непредвиденные проблемы.

...
objects_dirs := build/debug/db

$(objects_dirs):
	mkdir -p $@

$(OBJDIR)/%.o: $(root_source_dir)/%.c $(objects_dirs)
	gcc ляляля
...

Вроде логично. Для получения обьектника в этом каталоге - нужно сначала создать каталог.

make -d >1 ... Зависимость `build/debug/db' новее, чем цель `build/debug/db/dbconfig.o' ... Необходимо пересобрать цель `build/debug/db/dbconfig.o'

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

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

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

Вообще то время создания файла определяется с гораздо более высокой точностью, чем секунда. Но, если в директорию происходила запись - время изменения директории будет равняться времени записи.

$ ll ~ | grep tmp
drwxr-xr-x 12 aiv users  20K Дек  5 18:19 tmp

Как Вы понимаете, я свой tmp не сегодня создал...

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

хм а у меня fs примаунчена с опциями noatime,nodiratime - это только на чтение влияет, или на запись тоже?

вообще, да. Сейчас по-man-ил, есть ключик --full-time:

> ls --full-time
итого 108
drwxr-xr-x 2 chabapok chabapok  4096 2012-10-15 16:28:29.765363234 +0300 Desktop
....
drwxr-xr-x 2 chabapok chabapok  4096 2012-09-29 12:52:44.032221014 +0300 Music
drwxr-xr-x 2 chabapok chabapok  4096 2012-09-29 12:52:44.032221014 +0300 Pictures
..

как видно отсюда - да, вы правы — время запоминается точней секунды, и да я прав - все равно может существовать несколько директорий с одинаковым временем создания, а значит - и файлов. Проверим, с первой попытки:

> mkdir aaa;cd aaa;touch f1
> ls --full-time
-rw-rw-r-- 1 chabapok chabapok 0 2012-12-05 20:27:35.009501315 +0200 f1
chabapok@chabapok-xubuntu:/tmp/aaa$ cd ..
> ls --full-time
drwxrwxr-x 2 chabapok chabapok 4096 2012-12-05 20:27:35.009501315 +0200 aaa

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

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

Ваш пример - самый правильный, спасибо.

до тех пор, как в том каталоге появятся файлы.

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

Кури доки дальше, умник.

спасибо за инфу, но зачем грубить?

Prerequisite-Types.html

Вот это помогло, спасибо. Я эту доку видел, просто «order-only prerequisites» трактовал как последовательное выполнение зависимостей — в том порядке, в котором они перечислены. Поэтому не уделил этому пункту внимания. А оказывается это выполнение зависимостей без инвалидации цели.

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

но зачем грубить?

ты сразу с двумя разными анонимусами умудряешься разговаривать. :-)

просто «order-only prerequisites» трактовал как последовательное выполнение зависимостей

а я вроде бы в свое время это нагуглил именно на тему «как правильно создавать директории в макефайлах»

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

ты сразу с двумя разными анонимусами умудряешься разговаривать. :-)

да, но что мне еще остается делать? :))

Вобщем, вопрос считаю решеным. Всем принимавшим участие - спасибо.

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