【问题标题】:Undefined reference to rand() even thought it's included and defined对 rand() 的未定义引用甚至认为它已包含并已定义
【发布时间】:2016-11-01 02:09:29
【问题描述】:

我正在为我们在课堂上使用的自定义操作系统调度程序工作,但是当我尝试调用 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

【问题讨论】:

  • 收到该错误消息时使用了什么命令?
  • 发布了 makefile @DavidSchwartz
  • 您应该在帖子顶部添加一个大红色闪烁警告灯,表明您不是在普通 C 环境中工作,而是在嵌入式环境中工作。
  • 对不起@BodoThiesen,这是帖子的第一句话,但我会把它变成红色的
  • 没有问题,我只是没有意识到。

标签: c header-files scheduler


【解决方案1】:

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

【讨论】:

  • 首先感谢您的回答。我明白你在说什么,但如果他们在这里实现了 stdlib github.com/ppenna/nanvix/tree/master/src/lib/libc/stdlib 我不应该能够使用它吗?当我在发布此内容之前四处搜索时,我得出了与您相同的结论,但我想如果他们实现了它,我可以使用它。对吗?
  • @leofontes 你应该这样做,但快速检查一下,它似乎坏了。查看rand.h,您会看到它说有rand 的定义,但没有。目前尚不清楚您在做什么——您是在尝试构建操作系统本身还是在尝试为它构建应用程序?如果是前者,您确定允许操作系统使用该库吗?如果是后者,你为什么要输入make nanvix
  • 这是一个额外的奖励任务,我已经实现了提议的动态优先级,但现在我正在尝试为这个操作系统上的进程构建一个彩票调度程序。我不是在作业上寻求帮助,只是想了解发生了什么。我尝试在 .h 文件上声明 rand 函数,但它仍然不起作用,我会尝试修复库。谢谢你的帮助大卫。 :)
  • 编写函数原型,如“int rand(void);”在头文件中并包含该文件仅向编译器承诺“某处有该名称的函数”。如果缺少该函数,链接器将向您发出上面引用的错误消息。
  • 是的,所以我知道这不是最优雅的解决方案,但我从 sched.h 中的 rand.c 文件重写了它,它通过了建议的测试,但我会尝试坐下来写操作系统的 TA,因为我很确定他犯了一个错误哈哈,出于好奇,我会及时通知你们,但非常感谢,让我对情况有了很好的了解。
【解决方案2】:

您需要像这样链接自己的 c 库实现:

$ gcc -LPATH -lc $object_files -o executable

PATH 是你自己的 libc 的相对路径

或者...也许您最好听听 David Schwartz 的意见,他已经指出,您必须自己实现 rand。这里的意思是:你需要在内核中实现它,因为我猜,sched.c 是属于你的内核的一个文件,所以你不能使用 stdclib 函数。

【讨论】:

  • 我正在使用 makefile,我该如何添加它?抱歉,我还在学习 C
  • 忘记我的答案。
  • 请查看我对大卫回答的评论@BodoThiesen
  • 是的,我读过。你有一个内核。你有一个libstdc。但是在你的内核中,你的 libstdc 代码是不可访问的,对吧?这不是“你的”代码库,你只是在破解它,对吧?是的,你不是佩德罗。因此,您必须将 rand 函数从 libstdc 复制并粘贴到内核。
  • 是的,它被交给我们来破解和实现调度程序的一些功能。我想我也会尝试修复这个库,谢谢你的帮助。
猜你喜欢
  • 2014-10-05
  • 1970-01-01
  • 1970-01-01
  • 2018-08-27
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 1970-01-01
相关资源
最近更新 更多