2015-04-16 7 views
0

Выход make выглядит следующим образомМой Makefile пытается создать каталог,

gcc -Wall -Wextra -std=c99 -o bin/test src/obj/ src/obj/main.o src/obj/test.o 
/usr/bin/ld: cannot find src/obj/: File format not recognized 
collect2: error: ld returned 1 exit status 
make: *** [test] Error 1 

Как вы можете видеть, выполняется команда компиляции пытается скомпилировать Src/как файл/объект объекта. Мое лучшее предположение заключается в том, что как-то он был указан в переменной OBJ.

EDIT: Это рабочий файл. После некоторой отладки я сделал следующие изменения.

Это не работает. К тому времени, когда они были скомпилированы, все пути к файлам были перепутаны. Так это ...

# object directory 
OBJ_DIR=$(SRC_DIR)/obj 

# souce files 
SRC=$(wildcard $(SRC_DIR)/*.c) 

# object files 
OBJ=$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC)) # still directories in OBJ list causing problems 

стал этим ...

# object directory 
OBJ_DIR=obj 

# souce files 
SRC=$(patsubst $(SRC_DIR)/%.c,%.c,$(wildcard $(SRC_DIR)/*.c)) 

# object files 
OBJ=$(patsubst %.c,%.o,$(SRC)) 

и это ...

# rule that individual objects rely on .c versions and .h files 
# needs to compile to .o files, then compile to executable 
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(DEPS) 
    $(CC) -c -o [email protected] $< $(CFLAGS) 

# actual compile commands 
$(PROJ_NAME): $(OBJ_DIR)/$(OBJ) 
    $(CC) $(CFLAGS) -o $(TARGET) $(OBJ_DIR)/$(OBJ) 

стал этим ...

# rule that individual objects rely on .c versions and .h files 
# needs to compile to .o files, then compile to executable 
%.o: $(SRC_DIR)/%.c $(DEPS) 
    $(CC) -c -o [email protected] $< $(CFLAGS) 

# actual compile commands 
$(PROJ_NAME): $(SRC_DIR)/$(OBJ_DIR)/$(OBJ) 
    $(CC) $(CFLAGS) -o $(TARGET) $(SRC_DIR)/$(OBJ_DIR)/$(OBJ) 

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

+0

Используйте [remake] (http://bashdb.sourceforge.net/remake/) как 'remake -x' или' make -trace', чтобы понять, что происходит (при условии GNU make & Linux). –

ответ

0

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

Вот еще некоторые советы и замечания:

Вы можете использовать оператор := для оценки макросов во время синтаксического анализа, которые могут быть более подходящими для $(wildcard..) и $(shell...) расширений.

SRCS:=$(wildcard $(SRC_DIR)/*.c) 

Для ясности, вы должны использовать множественные идентификаторы для списков вещей: SRCS и OBJS. OBJS должен быть просто списком объектных файлов с включенным путем. Я не понимаю, почему вы настаиваете на удалении путей из списков файлов источников и объектов. Gnu Создание общих правил позволяет легко указать разные параметры компиляции для разных исходных файлов и/или каталогов объектов. Вы можете воспользоваться этим, чтобы сделать разные цели, такие как 32 и 64 битные версии, из тех же источников и позволить им сосуществовать без конфликтов.

Конечная цель должна быть простой:

$(PROJ_NAME): $(OBJS) 
    $(CC) $(CFLAGS) $(LDFLAGS) -o [email protected] $(OBJS) 
+0

Те, похоже, не работают. Можете ли вы объяснить, что не так с конечной целью? Список в 'OBJ' должен быть только одним файлом, требующим полного пути к ним. Я здесь не прав? – Charles

1

Я попробовал ваш Makefile с src каталогом, содержащим a.c файл.

Похоже, что $(OBJ_DIR)/$(OBJ) распространяется до src/obj/ src/obj/a.o.Переменная $(OBJ), вероятно, содержит пустые строки или пробелы

+0

Это имело бы смысл. Как я могу очистить их? – Charles

3

тезисах две линии

$(PROJ_NAME): $(OBJ_DIR)/$(OBJ) 
    $(CC) $(CFLAGS) -o $(TARGET) $(OBJ_DIR)/$(OBJ) 

, вероятно, неверно, так как $(OBJ) уже содержит $(OBJ_DIR)

Так используйте

$(PROJ_NAME): $(OBJ) 
     @echo OBJ= $(OBJ) at= [email protected] caret= $^ 
     $(COMPILE.c) $(CFLAGS) -o [email protected] $^ 

вместо этого. Узнайте больше о GNU make builtin rules (вы получите их с make -p). Когда вы будете удовлетворены, удалите отладочную строку @echo.

Как я заметил, использовать remake в remake -x или make --trace, чтобы понять, что происходит (предполагая, что GNU сделать & Linux).

Возможно, вы захотите использовать функцию strip для удаления пробелов в переднем и заднем пространстве, например.

OBJ= $(strip $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC))) 

Убедитесь, что ваш OBJ_DIR определение (и другие определения в вашем Makefile) не содержит хвостовые пробелы. Не записывайте комментарии в них:

#be sure that following line does not have comments or trailing spaces 
OBJ= $(strip $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC))) 

Ввод # комментарии в строке, определяющей сделать переменные очень плохая привычка. Вы должны поместить строки комментариев до или после строки определения.

+0

Да, я использую Ubuntu. Ремейк говорит мне, что это линия 61 - линия, на которую вы указали. Но я получаю ту же ошибку в обеих версиях. – Charles

+0

И я дважды проверил все строки и удалил комментарии к концу строки. Еще не повезло. – Charles

+0

Затем инвестируйте больше своего времени, используя 'remake -x' и' make -trace' соответственно –

Смежные вопросы