我正在编写一个操作系统,并为它制作一个标准的lib(称为' feta')。 Eclipse为我构建了一个libfeta.a
文件,我从我的操作系统中引用了该文件。这是我的makefile(我可能会遗漏一些重要的东西,我一直在添加和删除标记,试图让它工作):
# Makefile for Aura
# It can be structured way better, but it still beats manually compilation.
CC=i686-elf-g++ # Both the compiler and assembler need crosscompiled http://wiki.osdev.org/GCC_Cross-Compiler
AS=nasm
CFLAGS=-ffreestanding -Wall -Wextra #-Werror # Considering removing Werror as it can be annoying
LDFLAGS=-T utils/linker.ld -melf_i386
SOURCES=kernel/kernel.cpp kernel/gdt.s kernel/idt.s utils/linker.ld boot/boot.s # This will likely increase
OUT=build/kernel.o build/boot.o build/gdt.o build/idt.o
INCLUDE=-I"../mish/include" -I"../feta/include"
LIBS=-L"../feta/Debug" -lfeta #../feta/Debug/libfeta.a #-L"../feta/Debug" -L"../mish/Debug" -lmish -lfeta
all: compile
compile: compile-os
compile-os: $(SOURCES)
$(AS) -f elf boot/boot.s -o build/boot.o
$(AS) -f elf kernel/gdt.s -o build/gdt.o
$(AS) -f elf kernel/idt.s -o build/idt.o
@echo -- compiling or something --
$(CC) -c kernel/kernel.cpp -o build/kernel.o $(CFLAGS) -O2 -nostdlib $(INCLUDE)
@echo -- Linking or something --
$(CC) -T utils/linker.ld $(CFLAGS) -O2 -nostdlib $(OUT) $(INCLUDE) -o build/aura.bin $(LIBS)
@echo
@echo Compiation of Asura succeeded, boot with \"make run-os\"
@echo
run-os: build/asiago.bin
qemu-system-i386 -kernel build/aura.bin
debug-os: $(SOURCES)
$(AS) boot/boot.s -o build/boot.o
$(AS) kernel/interrupt.s -o build/interrupt.o
$(AS) -f elf kernel/gdt.s -o build/gdt.o
$(AS) -f elf kernel/idt.s -o build/idt.o
$(CC) -c kernel/kernel.cpp -o build/kernel.o $(CFLAGS) -g -std=gnu99 -O0 $(INCLUDE)
$(CC) -T utils/linker.ld -o build/aura.bin $(CFLAGS) -g -O0 -nostdlib $(OUT) $(INCLUDE) $(LIBS)
@echo
@echo Compilation of Asiago with debugging symbols and \-O0 succeeded, booting QEMU with debugging flags, connect with gdb.
@echo
qemu-system-i386 -d int,pcall -s -S -kernel build/aura.bin
elf: $(OUT)
ld $(LDFLAGS) $(OUT) -o build/kernel.elf
iso: build/kernel.elf
cp build/kernel.elf iso/boot/kernel.elf
genisoimage -R \
-b boot/grub/stage2_eltorito \
-no-emul-boot \
-boot-load-size 4 \
-A os \
-input-charset utf8 \
-quiet \
-boot-info-table \
-o build/asiago.iso \
iso
clean:
rm build/*o build/*bin build/*elf build/*iso
这是make
日志:
chris@cranberry ~/git/aura % make
nasm -f elf boot/boot.s -o build/boot.o
nasm -f elf kernel/gdt.s -o build/gdt.o
nasm -f elf kernel/idt.s -o build/idt.o
-- compiling or something --
i686-elf-g++ -c kernel/kernel.cpp -o build/kernel.o -ffreestanding -Wall -Wextra -O2 -nostdlib -I"../mish/include" -I"../feta/include"
In file included from kernel/kernel.cpp:24:0:
kernel/idt.cpp: In function 'void printk(int, char*, const char*, ...)':
kernel/idt.cpp:39:17: warning: unused parameter 'severity' [-Wunused-parameter]
void printk(int severity, char * type, const char *fmt, ...) {
^~~~~~~~
kernel/idt.cpp:39:34: warning: unused parameter 'type' [-Wunused-parameter]
void printk(int severity, char * type, const char *fmt, ...) {
^~~~
kernel/idt.cpp: In function 'void fault_handler(regs*)':
kernel/idt.cpp:259:47: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->err_code, exception_messages[r->int_no]);
^
kernel/idt.cpp:262:45: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->gs, r->fs, r->es, r->ds, r->cs, r->ss);
^
kernel/idt.cpp:264:41: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->useless_value, r->ebp, r->useresp);
^
kernel/idt.cpp:267:27: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->ebx, r->ecx, r->edx);
^
kernel/idt.cpp:270:38: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->esi, r->edi, r->eip, r->eflags);
^
kernel/idt.cpp:275:47: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->err_code, exception_messages[r->int_no]);
^
kernel/idt.cpp:278:45: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->gs, r->fs, r->es, r->ds, r->cs, r->ss);
^
kernel/idt.cpp:280:41: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->useless_value, r->ebp, r->useresp);
^
kernel/idt.cpp:283:27: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->ebx, r->ecx, r->edx);
^
kernel/idt.cpp:286:38: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
r->esi, r->edi, r->eip, r->eflags);
^
In file included from kernel/../modules/clock/clock.cpp:5:0,
from kernel/kernel.cpp:27:
kernel/../modules/clock/pit.cpp: In function 'void pitInterrupt(registers_t*)':
kernel/../modules/clock/pit.cpp:12:39: warning: unused parameter 'regs' [-Wunused-parameter]
static void pitInterrupt(registers_t* regs) {
^~~~
In file included from kernel/../modules/clock/clock.cpp:7:0,
from kernel/kernel.cpp:27:
kernel/../modules/clock/rtc.cpp: In function 'void rtcInterrupt(registers_t*)':
kernel/../modules/clock/rtc.cpp:10:39: warning: unused parameter 'regs' [-Wunused-parameter]
static void rtcInterrupt(registers_t* regs) {
^~~~
In file included from kernel/kernel.cpp:29:0:
kernel/../modules/keyboard/keyboard.cpp: In function 'void keyboardInterrupt(registers_t*)':
kernel/../modules/keyboard/keyboard.cpp:11:44: warning: unused parameter 'regs' [-Wunused-parameter]
static void keyboardInterrupt(registers_t* regs) {
^~~~
-- Linking or something --
i686-elf-g++ -T utils/linker.ld -ffreestanding -Wall -Wextra -O2 -nostdlib build/kernel.o build/boot.o build/gdt.o build/idt.o -I"../mish/include" -I"../feta/include" -o build/aura.bin -L"../feta/Debug" -lfeta
/home/chris/opt/cross/lib/gcc/i686-elf/6.1.0/../../../../i686-elf/bin/ld: warning: section `.bss' type changed to PROGBITS
build/kernel.o: In function `free(unsigned char*, unsigned int)':
kernel.cpp:(.text+0x18d5): undefined reference to `List<Block*>::isEmpty()'
kernel.cpp:(.text+0x18ed): undefined reference to `List<Block*>::size()'
kernel.cpp:(.text+0x18fe): undefined reference to `__cxa_allocate_exception'
kernel.cpp:(.text+0x190e): undefined reference to `typeinfo for char const*'
kernel.cpp:(.text+0x1914): undefined reference to `__cxa_throw'
kernel.cpp:(.text+0x192d): undefined reference to `List<Block*>::get(unsigned long long)'
kernel.cpp:(.text+0x1974): undefined reference to `List<Block*>::indexOf(Block*)'
kernel.cpp:(.text+0x198a): undefined reference to `List<Block*>::add(Block*, unsigned long long)'
kernel.cpp:(.text+0x19ca): undefined reference to `List<Block*>::indexOf(Block*)'
kernel.cpp:(.text+0x19fe): undefined reference to `List<Block*>::size()'
kernel.cpp:(.text+0x1a13): undefined reference to `List<Block*>::indexOf(Block*)'
kernel.cpp:(.text+0x1a28): undefined reference to `List<Block*>::get(unsigned long long)'
kernel.cpp:(.text+0x1a8d): undefined reference to `__cxa_allocate_exception'
build/kernel.o: In function `allocateMemory(unsigned int)':
kernel.cpp:(.text+0x1ab9): undefined reference to `List<Block*>::size()'
kernel.cpp:(.text+0x1aca): undefined reference to `__cxa_allocate_exception'
kernel.cpp:(.text+0x1ada): undefined reference to `typeinfo for char const*'
kernel.cpp:(.text+0x1ae0): undefined reference to `__cxa_throw'
kernel.cpp:(.text+0x1b01): undefined reference to `List<Block*>::get(unsigned long long)'
kernel.cpp:(.text+0x1b2b): undefined reference to `List<Block*>::remove(unsigned long long)'
kernel.cpp:(.text+0x1bdb): undefined reference to `List<Block*>::remove(unsigned long long)'
build/kernel.o: In function `free(unsigned char*, unsigned int)':
kernel.cpp:(.text+0x19a1): undefined reference to `List<Block*>::size()'
kernel.cpp:(.text+0x1a83): undefined reference to `List<Block*>::add(Element<Block*>*)'
../feta/Debug/libfeta.a(memory.o): In function `defaultMemoryAllocator(unsigned int)':
/home/chris/git/feta/Debug/../src/memory.cpp:12: undefined reference to `__cxa_allocate_exception'
/home/chris/git/feta/Debug/../src/memory.cpp:12: undefined reference to `typeinfo for char const*'
/home/chris/git/feta/Debug/../src/memory.cpp:12: undefined reference to `__cxa_throw'
collect2: error: ld returned 1 exit status
Makefile:16: recipe for target 'compile-os' failed
make: *** [compile-os] Error 1
它似乎陷入了这个阶段:$(CC) -T utils/linker.ld.....
基于我有限的C / C ++经验,我尝试在我的头文件中添加extern "C"
内容,但这不起作用,因为他们的C ++方法重载和东西不会工作所以...
我可以确认目录路径是正确的,以及使用相同的编译器(i686-elf-g++
)构建(feta和OS)。 Eclipse允许我扩展lib,我在那里看到列表二进制文件(以及其他一些文件)。
这里是我的list.h(在feta / include中),如果这有帮助的话:
/*
* list.h
*
* Created on: May 8, 2016
* Author: chris
*/
#ifndef INCLUDE_LIST_H_
#define INCLUDE_LIST_H_
#include <int.h>
#include <bool.h>
template<typename T> struct Element {
T value;
Element<T>* next;
};
template<typename T> class List {
private:
Element<T>* first;
Element<T>* getElement(uint64 index);
uint64 length = 0;
public:
uint64 size();
bool isEmpty();
bool isLast(uint64 index);
uint64 indexOf(T item);
T get(uint64 index);
void add(Element<T>* element);
void add(T item);
void add(T item, uint64 index);
T remove(uint64 index);
};
#endif /* INCLUDE_LIST_H_ */
以及list.cpp:
/*
* list.c
*
* Created on: May 8, 2016
* Author: chris
*/
#include <list.h>
#include <memory.h>
#include <errors.h>
template<typename T>
uint64 List<T>::size() {
return length;
}
template<typename T>
bool List<T>::isEmpty() {
return size() == 0;
}
template<typename T>
bool List<T>::isLast(uint64 index) {
return index == size() - 1;
}
template<typename T>
uint64 List<T>::indexOf(T item) {
for (int i = 0; i < size(); i++) {
if (get(i) == item) {
return i;
}
}
return -1;
}
template<typename T>
Element<T>* List<T>::getElement(uint64 index) {
Element<T>* element = first;
for (int i = 0; i < index - 1; i++) {
if (element->next == 0) {
throw INDEX_OUT_OF_BOUNDS;
}
element = element->next;
}
return element;
}
template<typename T>
T List<T>::get(uint64 index) {
return getElement(index).value;
}
template<typename T>
void List<T>::add(Element<T>* element) {
if (size() == 0) {
first = element;
} else {
getElement(size() - 1).after = element;
}
}
template<typename T>
void List<T>::add(T item) {
Element<T>* element = getMemory(sizeof(Element<T> ));
element->value = item;
add(element);
}
template<typename T>
void List<T>::add(T item, uint64 index) {
Element<T>* newElement = getMemory(sizeof(Element<T> ));
newElement->value = item;
// update references
if (size() == 0) { // initial
first = newElement;
} else if (index == 0) { // at the beginning
Element<T>* after = getElement(index);
newElement->next = after;
first = newElement;
} else if (index == size() - 1) { // at the end
Element<T>* before = getElement(index);
before->next = newElement;
} else { // in the middle
Element<T>* before = getElement(index - 1);
Element<T>* after = getElement(index);
before->next = newElement;
newElement->next = after;
}
length++;
}
template<typename T>
T List<T>::remove(uint64 index) {
Element<T>* removed = getElement(index);
T item = removed->item;
free(removed);
length--;
// update references
if (size() == 0) {
throw INDEX_OUT_OF_BOUNDS;
} else if (index == 0) { // at the beginning
first = getElement(index + 1);
} else if (index == size() - 1) { // at the end
Element<T>* before = getElement(index - 1);
before->next = 0;
} else { // in the middle
Element<T>* before = getElement(index - 1);
Element<T>* after = getElement(index + 1);
before->next = after;
}
return item;
}
我非常感谢任何帮助,因为我已经有好几周了。)