对静态库

时间:2016-05-12 16:10:31

标签: c++ gcc linker

我正在编写一个操作系统,并为它制作一个标准的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;
}

我非常感谢任何帮助,因为我已经有好几周了。)

0 个答案:

没有答案