-1

I'm currently working on a C project, but I'm stuck on what seems to be a simple problem...

My files are main.c, main.h, fun1.c, fun2.c and fun3.c.

main.h is included in main.c, fun1, fun2 and fun3 (respectively in fun1.C, fun2.c and fun3.c files) are used by a function in main.c, and the fun1, fun2 and fun3 functions are declared in main.h like that:

extern int fun1(unsigned);
extern int fun2(int, int, int);
extern int fun3(int, int);

But when I try to compile the code, I get these errors

main.c:12: undefined reference to 'fun1'
main.c:17: undefined reference to 'fun2'
main.c:25: undefined reference to 'fun3'

Did I miss something about the way extern works? Thanks for your answers.

The project is actually a lot more complex since I am working on a kernel, but I simplified it. This is a work that my teacher gave me, and I'm trying to modify the code as less as possible, that's why I'm sticking to the use of extern.


UPDATE

As the problem seems to lie somewhere else, I'm going to show you my file system.

My files are sem.c, sem.h, semget.c, semctl.c and semop.c.

sem.h is included in sem.c, semget, semctl and semop (respectively in semget.C, semctl.c and semop.c files) are used by a function in sem.c, and the semget, semctl and semop functions are declared as extern in sem.h (same as before, just changed back the names).

At some point in the makefile (don't ask me what the makefile is doing, I have no idea because of its complexity), the file syscalls.c is used:

#include <nanvix/const.h>
#include <nanvix/syscall.h>

/*
 * System calls table.
 */
PUBLIC void (*syscalls_table[NR_SYSCALLS])(void)  = {
    (void (*)(void))&sys_alarm,
    ...
    (void (*)(void))&semget,
    (void (*)(void))&semctl,
    (void (*)(void))&semop
};

The syscalls.c file include the syscall.h file:

#ifndef NANVIX_SYSCALL_H_
#define NANVIX_SYSCALL_H_

#include <nanvix/const.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <ustat.h>
#include <utime.h>

/* Number of system calls. */
#define NR_SYSCALLS 51

/* System call numbers. */
#define NR_alarm 0
#define NR_brk 1
...
#define NR_semget 48
#define NR_semctl 49
#define NR_semop 50

#ifndef _ASM_FILE_

/* System calls prototypes. */
EXTERN unsigned sys_alarm(unsigned seconds);
EXTERN int sys_brk(void *ptr);
...
EXTERN int semget(unsigned key);
EXTERN int semctl(int semid, int cmd, int val);
EXTERN int semop(int semid, int op);

#endif /* _ASM_FILE_ */
#endif /* NANVIX_SYSCALL_H_ */

The exact error is what follows:

sys/syscalls.o:(.data+0xc0): undefined reference to `semget'
sys/syscalls.o:(.data+0xc4): undefined reference to `semctl'
sys/syscalls.o:(.data+0xc8): undefined reference to `semop'
sys/sem.o: In function `create':
/home/windea/workshop/ricm4/as/nanvix/src/kernel/sys/sem.c:12: undefined reference to `semget'
/home/windea/workshop/ricm4/as/nanvix/src/kernel/sys/sem.c:17: undefined reference to `semctl'
sys/sem.o: In function `down':
/home/windea/workshop/ricm4/as/nanvix/src/kernel/sys/sem.c:25: undefined reference to `semop'
sys/sem.o: In function `up':
/home/windea/workshop/ricm4/as/nanvix/src/kernel/sys/sem.c:33: undefined reference to `semop'
sys/sem.o: In function `destroy':
/home/windea/workshop/ricm4/as/nanvix/src/kernel/sys/sem.c:41: undefined reference to `semctl'
makefile:67: recipe for target 'all' failed
make[2]: *** [all] Error 1

And finally, the last command line executed by make before the error was:

i386-elf-ld -T arch/x86/link.ld arch/x86/utilities.o arch/x86/io.o arch/x86/boot.o arch/x86/hooks.o arch/x86/setup.o arch/x86/hwint.o arch/x86/8259.o arch/x86/exception.o arch/x86/clock.o arch/x86/hal.o dev/dev.o dev/ata/ata.o dev/klog/klog.o dev/ramdisk/ramdisk.o dev/tty/console.o dev/tty/keyboard.o dev/tty/tty.o fs/file.o fs/block.o fs/super.o fs/buffer.o fs/pipe.o fs/inode.o fs/fs.o init/main.o lib/kstrncpy.o lib/kpanic.o lib/kprintf.o lib/kvsprintf.o lib/krand.o lib/kmemcpy.o lib/ksrand.o lib/kmemdump.o lib/kstrlen.o lib/kstrcmp.o lib/kstrcpy.o lib/kmemset.o lib/kstrncmp.o lib/bitmap.o mm/mm.o mm/paging.o mm/region.o pm/die.o pm/sleep.o pm/pm.o pm/sched.o pm/signal.o sys/times.o sys/stat.o sys/setgid.o sys/alarm.o sys/shutdown.o sys/kill.o sys/chmod.o sys/ioctl.o sys/umask.o sys/close.o sys/_exit.o sys/ustat.o sys/setegid.o sys/getgid.o sys/fork.o sys/getpgrp.o sys/nice.o sys/chroot.o sys/brk.o sys/syscalls.o sys/ps.o sys/wait.o sys/sync.o sys/unlink.o sys/setpgrp.o sys/signal.o sys/pause.o sys/link.o sys/read.o sys/gticks.o sys/fcntl.o sys/utime.o sys/write.o sys/geteuid.o sys/chdir.o sys/pipe.o sys/getegid.o sys/setuid.o sys/access.o sys/execve.o sys/getppid.o sys/chown.o sys/uname.o sys/lseek.o sys/sem.o sys/open.o sys/seteuid.o sys/getuid.o sys/getpid.o  -o /home/windea/workshop/ricm4/as/nanvix/bin/kernel

I have no idea if this will help anyone to understand my issue, but now I think you can have a better grasp of what's going on at least.

Windea
  • 23
  • 5

1 Answers1

0

Looks like you are compiling only the main.c and not fun1.c, fun2.c and fun3.c

You can try to compile as follows:

gcc -c main.c -o main.o
gcc -c fun1.c -o fun1.o
gcc -c fun2.c -o fun2.o
gcc -c fun3.c -o fun3.o
gcc main.o fun1.o fun2.o fun3.o -o all.out
SHR
  • 7,940
  • 9
  • 38
  • 57
  • I made a more detaillled explaination of my project if you wanna take a look. I cannot modify the Makefile, but it's supposed to be perfect (the project is on a kernel used to teach students how kernels work) so there shouldn't be any problem with it. – Windea Feb 21 '19 at 12:34
  • @Windea For each file.c you must have file.o. I didn't find for example **semget.o** in the linker command line you gave. so clearly it missing. – SHR Feb 21 '19 at 13:57
  • Thanks to you, I kind of understood how the makefile worked (it was just calling multiple other makefiles). And indeed, it wasn't making the object files, because I created a new directory so I just extended the wildcard to the new directory and it works! Thanks a lot! – Windea Feb 21 '19 at 15:08