Почему этот make-файл не применяется включает в себя все объекты? - PullRequest
1 голос
/ 06 июля 2011

Этот make-файл работает не так, как я ожидаю.Я хочу, чтобы он создавал файлы .o для каждого файла .c в текущем каталоге и подкаталогах и помещал их в статическую библиотеку.Тем не менее, он перестает применять мой $ (INCS) после первого или второго файла.Когда он пытается собрать второй файл .o, я не вижу пути -I в строке сборки, и он жалуется на то, что в нем нет заголовочного файла.Имена были обобщены для упрощения вещей.Я использую Cygwin на Windows XP.Я использую кросс-компилятор ARM, который не находится под деревом Cygwin.Я основал этот make-файл на ответе здесь .Существует всего около двух десятков файлов .c, поэтому создание таких файлов зависимостей не составляет большого труда.

# Project specific options
CC = my-cross-gcc
INCS := -I. -Iinc 
INCS += -Imy/inc/path

CFLAGS := -Wall -fPIC -static -cross-compiler-specific-options

OUT := bin/libmylib.a

MKDIR:=mkdir -p

### Generic C makefile items below:

# Add .d to Make's recognized suffixes.
SUFFIXES += .d

NODEPS:=clean
#Find all the C files in this directory, recursively
SOURCES:=$(shell find . -name "*.c")

#These are the dependency files
DEPFILES:=$(patsubst %.c,%.d,$(SOURCES))
OBJS:= $(patsubst %.c,%.o,$(SOURCES))

#Don't create dependencies when we're cleaning, for instance
ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
    -include $(DEPFILES)
endif

#This is the rule for creating the dependency files
%.d: %.c
    $(CC) $(INCS) $(CFLAGS) -MM -MT '$(patsubst %.c, %.o,$(patsubst %.c,%.o,$<))' $< > $@

#This rule does the compilation
%.o: %.c %.d %.h
    $(CC) $(INCS) $(CFLAGS) -o $@ -c $<

# Now create a static library
all: $(OBJS)
    @$(MKDIR) bin
    ar rcsvq $(OUT) $(OBJS)

clean: 
    rm -rf $(OBJS) $(OUT) $(DEPFILES)

Почему этот make-файл не применяет $ (INCS) при создании последующих файлов .o?Как мне это исправить?Выходные данные выглядят примерно так:

$ make all
my-cross-gcc -I. -Iinc -Imy/inc/path -<compiler options> -o firstfile.o -c firstfile.c
my-cross-gcc -I. -Iinc -Imy/inc/path -<compiler options> -o secondfile.o -c secondfile.c
my-cross-gcc -<compiler flags> -o thirdfile.o -c thirdfile.c
thirdfile.c:23:18: fatal error: myinc.h: No such file or directory
compilation terminated.

Когда я иду в командную строку и набираю строку gcc, чтобы собрать третий файл.o и использовать пути -I, объектный файл успешно создается.

Ответы [ 3 ]

3 голосов
/ 06 июля 2011

Здесь есть два разных механизма для работы с заголовочными файлами:

Когда компилятор пытается собрать foo.o из foo.c, а в foo.c он встречает #include "foo.h", он ищет foo.h. Флаги -I указывают, где искать. Если он вызывается без флагов, которые ему нужно найти foo.h, он будет жаловаться и умрет.

Когда Make пытается собрать foo.o и, рассматривая какое правило использовать, он смотрит на предварительные условия. Предпосылки для вашего правила foo.c foo.d foo.h, поэтому он ищет эти предпосылки. Как узнать, где находится foo.h? Обратите внимание, что флаг компилятора внутри одной из его команд бесполезен - он не будет делать никаких выводов по этому поводу. Если он не может найти (и не знает, как сделать) предварительное условие, он отклонит это правило и будет искать другое, такое как неявное правило %.o, которое ничего не знает о вашей переменной $ (INCS), и это приводит вас к проблеме, описанной выше.

Если это проблема (и вы можете проверить, посмотрев на расположение заголовков и выполнив некоторые эксперименты), у вас есть несколько вариантов:

A) Вы можете использовать неявное правило и его переменные. Просто добавьте INCS к CFLAGS, и вы, вероятно, получите желаемый результат. Это говорит компилятору, что делать, но все равно оставляет Make в неведении относительно зависимостей, поэтому вам, вероятно, придется дважды проверить правильность обработки зависимостей.

B) Вы можете указать Make, где искать заголовочные файлы:

vpath %.h inc my/inc/path

(Вы можете заметить, что это избыточно с вашей переменной INCS, а избыточность плохая - вы можете устранить эту избыточность, но я призываю вас сначала заставить ее работать.)

2 голосов
/ 06 июля 2011

Я собираюсь предположить, что у вас есть файлы с именем firstfile.h, secondfile.h, но нет файла с именем thirdfile.h?

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

1 голос
/ 06 июля 2011

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

...