старый Makefile для сборки библиотеки больше не работает под FreeBSD - PullRequest
0 голосов
/ 27 сентября 2018

В последнее время я мало занимался программированием на C, но недавно я повторно посетил старый проект и обнаружил, что старый Makefile для сборки библиотеки под FreeBSD больше не работает.Вот очень упрощенная версия Makefile, которая раньше работала:

TEST    = Test
LIBTEST = lib$(TEST).a

CC      = cc

.PRECIOUS: $(LIBTEST)

all: $(LIBTEST)

LIBSRC  = test.c

# Do not automatically delete library source files
.SECONDARY: $(LIBSRC)

LIBOBJ  = $(LIBSRC:%.c=%.o)

$(LIBTEST): $(LIBTEST)($(LIBOBJ))
        $(AR) $(ARFLAGS) $@ $?
        rm -f $?

clean:
        @rm -f *.o $(LIBTEST)

И вот тривиальная программа на C, подходящая для этого:

/* test.c */
#include <stdio.h>

int
test(char const *text)
{
    printf("%s\n", text);
    return 1;
}

Это похоже на зависимость директивы Makefile:

$(LIBTEST): $(LIBTEST)($(LIBOBJ))

больше не работает.Это приводит к:

 ar -crD libTest.a
 rm -f

Я безуспешно просматривал «создание человека».

Одна вещь, которая озадачивает меня, это то, что «создание человека» говорит: «Для более подробного описанияmake и makefiles, пожалуйста, обратитесь к PMake - A Tutorial. "

Это точно?У меня сложилось впечатление, что pmake был заменен на bsdmake в последних версиях FreeBSD - это источник моих проблем?

Примечание: меня не интересуют ответы, которые сводятся к "вы можете сделатьэто просто прекрасно с использованием GNU make "- это вопрос для FreeBSD make.

1 Ответ

0 голосов
/ 03 октября 2018
$(LIBTEST): $(LIBTEST)($(LIBOBJ))

предполагает, что предварительное условие $(LIBTEST) (здесь libTest.a) является $(LIBOBJ) (здесь test.o) членом этого архива, и я не совсем уверен, что make должен был бы завершитьот, но для меня (FreeBSD 11.0) он приходит с all (что на самом деле означает libTest.a) уже в актуальном состоянии (см. также пример ниже линейки).Изменение строки на:

$(LIBTEST): $(LIBOBJ)

Казалось бы, имеет смысл (и если я что-то пропустил, должно быть то, что вы хотите), объектный файл является обязательным условием для цели библиотеки, и правило обновляет библиотеку с помощьювсе предпосылки новее, чем цель ($?).

Что приводит меня к еще одному комментарию.То, что rm кажется не только ненужным, но на самом деле вредным, потому что это означает, что test.o всегда перекомпилируется при вызове make all, а библиотека всегда обновляется даже при отсутствии изменения источника (test.c), поскольку промежуточная предварительная цель являетсяне там (то есть устарело).


Я бы действительно получил такое поведение, даже если бы разрешил все вещи вокруг и обрезал бы Makefile до минимума:

$ ls
Makefile        test.c
$ cat Makefile 
libTest.a: libTest.a(test.o)
        $(AR) $(ARFLAGS) $@ $?
$ make
`libTest.a' is up to date.
$ ls
Makefile        test.c
...