Reputation: 927
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:
In function `gen_rand_number':
sched.c:(.text+0x5e): undefined reference to `rand'
Here is my sched.c file
#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
it is defined on: include/stdlib.h
and implemented on: src/lib/libc/stdlib/rand.c as follows:
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:
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
Upvotes: 0
Views: 5025
Reputation: 2514
You need to link in your own implementation of the c library somewhat like this:
$ gcc -LPATH -lc $object_files -o executable
where PATH is the relative path to your own 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.
Upvotes: 1
Reputation: 182769
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.
Upvotes: 4