2016-02-10 5 views
1

Я недавно решил начать использовать make-файлы вместо того, чтобы вводить каждую команду в файл bash, но при попытке скомпилировать ее при использовании одного из них я столкнулся с проблемой.Ошибки множественного определения при связывании кода C и ассемблера?

Я пытаюсь скомпилировать несколько файлов C и сборки, но продолжаю получать эту ошибку. Я triple проверил все файлы, и нет ничего плохого в них, поэтому я предполагаю, что это мой make-файл.

Вот ошибка, что я получаю:

… 
i686-elf-gcc -T linker.ld -o bin/kernel.bin -ffreestanding -O2 -nostdlib src/boot.o \ 
    src/gdt.o src/cgdt.o src/kernel.o -lgcc 
src/cgdt.o: In function `gdt_set_gate': 
cgdt.c:(.text+0x0): multiple definition of `gdt_set_gate' 
src/gdt.o:gdt.c:(.text+0x0): first defined here 
src/cgdt.o: In function `gdt_install': 
cgdt.c:(.text+0x70): multiple definition of `gdt_install' 
src/gdt.o:gdt.c:(.text+0x70): first defined here 
src/gdt.o: In function `gdt_install': 
gdt.c:(.text+0x17a): undefined reference to `gdt_flush' 
src/cgdt.o: In function `gdt_install': 
cgdt.c:(.text+0x17a): undefined reference to `gdt_flush' 
collect2: error: ld returned 1 exit status 
Makefile:17: recipe for target 'link' failed 
make: *** [link] Error 1 

И вот Makefile:

CC=i686-elf-gcc 
AS=i686-elf-as 
LINKER=i686-elf-gcc 

CFLAGS=-std=gnu99 -ffreestanding -O2 -Wall -Wextra -I./src/include 
LDFLAGS=-T linker.ld 

C_SOURCES = $(shell ls src/*.c) 
ASM_SOURCES = $(shell ls src/*.s) 
OBJECTS = $(ASM_SOURCES:.s=.o) $(C_SOURCES:.c=.o) 

all: $(OBJECTS) link 
clean: 
    -rm ./src/*.o 

link: 
    $(LINKER) $(LDFLAGS) -o bin/kernel.bin -ffreestanding -O2 -nostdlib $(OBJECTS) -lgcc 

.c.o: 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

.s.o: 
    $(AS) $< -o [email protected] 
+3

Ну, эти функции определены как в gdt.c, так и cgdt.c? – aschepler

+0

'LDFLAGS = -T linker.ld' выглядит неправильно. Разве это не должно быть 'LDFLAGS = -T'? –

+1

Проблема не имеет ничего общего с 'make' или вашим' makefile' как таковой, и все зависит от того, как ваш код в 'src/gdt.c' и' src/cgdt.c' определяет как внешне видимый символ 'gdt_set_gate()' и т. д. Вы забыли использовать '' static' перед 'inline' '(https://stackoverflow.com/questions/6312597/is-inline-without-static-or-extern-ever -useful-in-c99), когда вы указали свои функции как 'inline'? –

ответ

2

Похоже, это не make проблема, это то, что ваша команда НКУ Безразлично» т работы. Какую команду вы успешно использовали в своем сценарии bash?


Make имеет неявные правила для изготовления .o из .c, и для изготовления .o из .s. Вы можете настроить, что происходит, настроив некоторые переменные.

Кроме того, используйте .phony: link, так что это все еще происходит, если есть файл с именем link. Дайте ему зависимость от $(OBJECTS), чтобы он делался по мере необходимости. Или сообщите make реальное имя цели, которая будет построена.

bin/kernel.bin: $(OBJECTS) 
    some_command -o [email protected] ... 
Смежные вопросы