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

时间:2021-08-08 05:50:17

I'm working on the scheduler for a custom OS we are using in class, but when I try to call the rand() function, it gives me this error:

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

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

Here is my sched.c file

这是我的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);
}

So after a lot of Googling, I realized maybe the stdlib wasn't implemented on this OS, however I checked and

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

it is defined on: include/stdlib.h

它定义于:include / stdlib.h

and implemented on: src/lib/libc/stdlib/rand.c as follows:

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

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

I realize this is a quite specific problem, but I hope someone is able to help me out. Also, if more information is needed, please let me know.

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

If you want to look at the whole OS code

如果你想查看整个操作系统代码

Since this is coming up, I'm using a makefile:

由于这是即将到来,我正在使用makefile:

export 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 个解决方案

#1


4  

Since you're building a freestanding OS, not an application, you have no access to the standard library. If you look in the makefile, you'll see that it passes -nostdlib -nostdinc to the compiler and linker. If your codebase provides a PRNG, you can use it. Otherwise, you'll need to add an implementation of one.

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

#2


1  

You need to link in your own implementation of the c library somewhat like this:

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

$ gcc -LPATH -lc $object_files -o executable

where PATH is the relative path to your own libc

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

Or ... probably you should better listen to David Schwartz, who already pointed out, that you have to implement rand yourself. Here it means: You need to implement it in the kernel, because I guess, sched.c is a file belonging to your kernel, and so, the stdclib functions are not available to you.

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

#1


4  

Since you're building a freestanding OS, not an application, you have no access to the standard library. If you look in the makefile, you'll see that it passes -nostdlib -nostdinc to the compiler and linker. If your codebase provides a PRNG, you can use it. Otherwise, you'll need to add an implementation of one.

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

#2


1  

You need to link in your own implementation of the c library somewhat like this:

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

$ gcc -LPATH -lc $object_files -o executable

where PATH is the relative path to your own libc

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

Or ... probably you should better listen to David Schwartz, who already pointed out, that you have to implement rand yourself. Here it means: You need to implement it in the kernel, because I guess, sched.c is a file belonging to your kernel, and so, the stdclib functions are not available to you.

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