对rand()的未定义引用甚至认为包含和定义了它

时间:2016-11-01 02:09:30

标签: c header-files scheduler

我正在使用我们在课堂上使用的自定义操作系统的调度程序,但是当我尝试调用rand()函数时,它会给我这个错误:

In function `gen_rand_number':
sched.c:(.text+0x5e): undefined reference to `rand'

这是我的sched.c文件

#include <stdlib.h>
#include <signal.h>

PUBLIC int gen_rand_number(int min, int max) {
    int r;
    const int range = 1 + max - min;
    const int buckets = RAND_MAX / range;
    const int limit = buckets * range;  

    do {
        r = rand();
    } while (r >= limit);

    return min + (r / buckets);
}

所以经过很多谷歌搜索后,我意识到stdlib可能没有在这个操作系统上实现,但是我检查了

定义于:include / stdlib.h

并在:src / lib / libc / stdlib / rand.c上实现如下:

int rand(void)
{
    _next = (_next * 1103515245) + 12345;
    return ((_next >> 16) & 0x7fff);
}

我意识到这是一个非常具体的问题,但我希望有人能够帮助我。另外,如果需要更多信息,请告诉我。

If you want to look at the whole OS code

由于即将到来,我使用的是makefile:

出口EDUCATIONAL_KERNEL = 1

# Directories.
export BINDIR   = $(CURDIR)/bin
export SBINDIR  = $(BINDIR)/sbin
export UBINDIR  = $(BINDIR)/ubin
export DOCDIR   = $(CURDIR)/doc
export INCDIR   = $(CURDIR)/include
export LIBDIR   = $(CURDIR)/lib
export DOXYDIR  = $(CURDIR)/doxygen
export SRCDIR   = $(CURDIR)/src
export TOOLSDIR = $(CURDIR)/tools

# Toolchain
export CC = $(TARGET)-gcc
export LD = $(TARGET)-ld
export AR = $(TARGET)-ar

# Random number for chaos.
export KEY = 13

# Toolchain configuration.
export CFLAGS    = -I $(INCDIR)
export CFLAGS   += -DKERNEL_HASH=$(KEY) -DEDUCATIONAL_KERNEL=$(EDUCATIONAL_KERNEL)
export CFLAGS   += -std=c99 -pedantic-errors -fextended-identifiers
export CFLAGS   += -nostdlib -nostdinc -fno-builtin -fno-stack-protector
export CFLAGS   += -Wall -Wextra -Werror
export CFLAGS   += -Wstack-usage=3192 -Wlogical-op
export CFLAGS   += -Wredundant-decls -Wvla
export ASMFLAGS  = -Wa,--divide,--warn
export ARFLAGS   = -vq
export LDFLAGS   = -Wl,-T $(LIBDIR)/link.ld

# Resolves conflicts.
.PHONY: tools

# Builds everything.
all: nanvix documentation

# Builds Nanvix.
nanvix:
    mkdir -p $(BINDIR)
    mkdir -p $(SBINDIR)
    mkdir -p $(UBINDIR)
    cd $(SRCDIR) && $(MAKE) all

# Builds system's image.
image: $(BINDIR)/kernel tools
    mkdir -p $(BINDIR)
    bash $(TOOLSDIR)/build/build-img.sh $(EDUCATIONAL_KERNEL)

# Builds documentation.
documentation:
    doxygen $(DOXYDIR)/kernel.config

# Builds tools.
tools:
    mkdir -p $(BINDIR)
    cd $(TOOLSDIR) && $(MAKE) all

# Cleans compilation files.
clean:
    @rm -f *.img
    @rm -rf $(BINDIR)
    @rm -rf $(DOCDIR)/*-kernel
    cd $(SRCDIR) && $(MAKE) clean
    cd $(TOOLSDIR) && $(MAKE) clean

2 个答案:

答案 0 :(得分:4)

由于您构建的是独立操作系统,而不是应用程序,因此您无法访问标准库。如果你查看makefile,你会看到它将-nostdlib -nostdinc传递给编译器和链接器。如果您的代码库提供PRNG,您可以使用它。否则,您需要添加一个实现。

答案 1 :(得分:1)

您需要在自己的c库实现中链接,如下所示:

$ gcc -LPATH -lc $object_files -o executable

其中PATH是您自己的libc的相对路径

或者......可能你应该更好地听David Schwartz,他已经指出,你必须自己实施rand。这意味着:你需要在内核中实现它,因为我猜,sched.c是属于你内核的文件,因此,你无法使用stdclib函数。