Makefile: сборка в отдельном дереве каталогов - PullRequest
6 голосов
/ 15 апреля 2010

Мой проект (интерпретируемый язык) имеет стандартную библиотеку, состоящую из нескольких файлов, каждый из которых будет встроен в динамическую библиотеку .so, которую интерпретатор будет загружать по запросу пользователя (с директивой импорта). Каждый исходный файл находится в подкаталоге, представляющем его «пространство имен», например:

дерево библиотек http://img707.imageshack.us/img707/7299/screenshot1tv.png

В процессе сборки должен быть создан каталог "build", а затем, когда каждый файл компилируется, он должен создать свой каталог пространства имен внутри каталога "build", например, при компиляции

std/io/network/tcp.cc

он запускает команду mkdir с

mkdir -p build/std/io/network

Фрагмент файла Makefile:

STDSRC=stdlib/std/hashing/md5.cc \
       stdlib/std/hashing/crc32.cc \
       stdlib/std/hashing/sha1.cc \
       stdlib/std/hashing/sha2.cc \
       stdlib/std/io/network/http.cc \
       stdlib/std/io/network/tcp.cc \
       stdlib/std/io/network/smtp.cc \
       stdlib/std/io/file.cc \
       stdlib/std/io/console.cc \
       stdlib/std/io/xml.cc \
       stdlib/std/type/reflection.cc \
       stdlib/std/type/string.cc \
       stdlib/std/type/matrix.cc \
       stdlib/std/type/array.cc \
       stdlib/std/type/map.cc \
       stdlib/std/type/type.cc \
       stdlib/std/type/binary.cc \
       stdlib/std/encoding.cc \
       stdlib/std/os/dll.cc \
       stdlib/std/os/time.cc \
       stdlib/std/os/threads.cc \
       stdlib/std/os/process.cc \
       stdlib/std/pcre.cc \
       stdlib/std/math.cc

STDOBJ=$(STDSRC:.cc=.so)

all: stdlib

stdlib: $(STDOBJ)

.cc.so: 
    mkdir -p `dirname $< | sed -e 's/stdlib/stdlib\/build/'`
    $(CXX) $< -o `dirname $< | sed -e 's/stdlib/stdlib\/build/'`/`basename $< .cc`.so $(CFLAGS) $(LDFLAGS)

У меня два вопроса:

1 - Проблема в том, что команда make, я действительно не знаю, почему, не проверяет, был ли файл изменен, и запускает процесс сборки на ВСЕХ файлах, несмотря ни на что, поэтому, если мне нужно только собрать один файл, я должен собрать их все или использовать команду:

make path/to/single/file.so

Есть ли способ решить эту проблему?

2 - Есть ли способ сделать это "чище" без необходимости распространять все каталоги сборки с исходными кодами?

Спасибо

1 Ответ

12 голосов
/ 15 апреля 2010

Для 1) проблема в том, что цель вашего правила (stdlib /thing.so) не совсем то, что делает правило (build / something.so), поэтому Make всегда думает, что оно должно стать целью. Это должно исправить (я использую GNUMake):

STDOBJ=$(patsubst stdlib%.cc,build%.so, $(STDSRC))

all: stdlib

stdlib: $(STDOBJ)

build/%.so: stdlib/%.cc
    mkdir -p $(dir $@)
    $(CXX) $< -o $@ $(CFLAGS) $(LDFLAGS)

Для 2) Я не уверен, что вы имеете в виду. Если вам нужна структура директории сборки, которую вы описываете, она сделает это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...