I've these simple source files:
Header file
//header.h
#ifndef HEADER_H
#define HEADER_H
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <stdint.h>
#include <string.h>
void test_uint_to_mpz();
#endif
Implementation file
//src.c
#include "header.h"
void test_uint_to_mpz() {
char hex_string[200];
uint64_t var;
mpz_t mpz_var;
mpz_init(mpz_var);
printf("Please enter a hex string that fits a variable uint64_t : ");
scanf("%s",hex_string);
var = (uint64_t)strtol(hex_string,NULL,16);
mpz_set_ui(mpz_var,var);
printf("Your input value was: %llx\n",var);
printf("The mpz equivalent is: ");
mpz_out_str(stdout,16,mpz_var);
printf("\n");
mpz_clear(mpz_var);
}
Main
//main.c
#include "header.h"
int main(int argc, char** argv) {
test_uint_to_mpz();
return 0;
}
Then I try to compile using this simple line:
gcc src.c main.c -L/user/lcg/lib -o numericalTest -I./ -lgmp -O3 -static
Since I want to use a static linking. To me is fine, I'm quite sure that the installation of gmp is fine (see the -L option in my command line).
However then I have:
gcc src.c main.c -L/user/lcg/lib -o numericalTest -I./ -lgmp -O3 -static
/tmp/ccz2qa8j.o: In function `__gmpz_abs':
main.c:(.text+0x0): multiple definition of `__gmpz_abs'
/tmp/cc0jVOgJ.o:src.c:(.text+0x0): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_fits_uint_p':
main.c:(.text+0x20): multiple definition of `__gmpz_fits_uint_p'
/tmp/cc0jVOgJ.o:src.c:(.text+0x20): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_fits_ulong_p':
main.c:(.text+0x60): multiple definition of `__gmpz_fits_ulong_p'
/tmp/cc0jVOgJ.o:src.c:(.text+0x60): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_fits_ushort_p':
main.c:(.text+0x70): multiple definition of `__gmpz_fits_ushort_p'
/tmp/cc0jVOgJ.o:src.c:(.text+0x70): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_get_ui':
main.c:(.text+0xb0): multiple definition of `__gmpz_get_ui'
/tmp/cc0jVOgJ.o:src.c:(.text+0xb0): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_getlimbn':
main.c:(.text+0xd0): multiple definition of `__gmpz_getlimbn'
/tmp/cc0jVOgJ.o:src.c:(.text+0xd0): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_neg':
main.c:(.text+0x110): multiple definition of `__gmpz_neg'
/tmp/cc0jVOgJ.o:src.c:(.text+0x110): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_perfect_square_p':
main.c:(.text+0x130): multiple definition of `__gmpz_perfect_square_p'
/tmp/cc0jVOgJ.o:src.c:(.text+0x130): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_popcount':
main.c:(.text+0x150): multiple definition of `__gmpz_popcount'
/tmp/cc0jVOgJ.o:src.c:(.text+0x150): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_set_q':
main.c:(.text+0x180): multiple definition of `__gmpz_set_q'
/tmp/cc0jVOgJ.o:src.c:(.text+0x180): first defined here
/tmp/ccz2qa8j.o: In function `__gmpz_size':
main.c:(.text+0x190): multiple definition of `__gmpz_size'
/tmp/cc0jVOgJ.o:src.c:(.text+0x190): first defined here
/tmp/ccz2qa8j.o: In function `__gmpq_abs':
main.c:(.text+0x1a0): multiple definition of `__gmpq_abs'
/tmp/cc0jVOgJ.o:src.c:(.text+0x1a0): first defined here
/tmp/ccz2qa8j.o: In function `__gmpq_neg':
main.c:(.text+0x1c0): multiple definition of `__gmpq_neg'
/tmp/cc0jVOgJ.o:src.c:(.text+0x1c0): first defined here
/tmp/ccz2qa8j.o: In function `__gmpn_add':
main.c:(.text+0x1e0): multiple definition of `__gmpn_add'
/tmp/cc0jVOgJ.o:src.c:(.text+0x1e0): first defined here
/tmp/ccz2qa8j.o: In function `__gmpn_add_1':
main.c:(.text+0x360): multiple definition of `__gmpn_add_1'
/tmp/cc0jVOgJ.o:src.c:(.text+0x360): first defined here
/tmp/ccz2qa8j.o: In function `__gmpn_cmp':
main.c:(.text+0x570): multiple definition of `__gmpn_cmp'
/tmp/cc0jVOgJ.o:src.c:(.text+0x570): first defined here
/tmp/ccz2qa8j.o: In function `__gmpn_sub':
main.c:(.text+0x5a0): multiple definition of `__gmpn_sub'
/tmp/cc0jVOgJ.o:src.c:(.text+0x5a0): first defined here
/tmp/ccz2qa8j.o: In function `__gmpn_sub_1':
main.c:(.text+0x720): multiple definition of `__gmpn_sub_1'
/tmp/cc0jVOgJ.o:src.c:(.text+0x720): first defined here
collect2: error: ld returned 1 exit status
make: *** [output] Error 1
Where could be the problem?
Update: i post the makefile
CC=gcc
SRCS=src.c main.c
HEADER=header.h
OBJ_FILES=$(addsuffix ./,(basename $(SRCS)))
INCLUDES=-I./
FLAG=-lgmp -O3
output : $(SRCS) $(HEADER)
$(CC) $(SRCS) -L/user/lcg/lib -o numericalTest $(INCLUDES) $(FLAG) -static
clean :
rm *.o
Related
I have a header file command.h which contains all my variables and function declarations
//command.h
int someVar1;
int someVar2;
void modifying_loop (int a, int b);
int someVar3;
.
.
.
In another file my_algorithm.c I define the previously declared function modifying_loop and use some of the variables declared in the header in
//my_algorithm.c
#include "command.h"
void modifying_loop (int x, int y)
{
someVar1 = x+2;
someVar2 = y+2;
}
And I have my main file command.c I called the modifying_loop function like this :
#include "command.h"
int main ()
{
modifying_loop(5,6);
return 0;
}
I compile the it using gcc -o command command.c -lm -lpigpio -L/usr/lib/ which returns me
undefined reference to modifying_loop'
Then to tackle that I link the my_algorithm.c file by using
gcc -o command command.c my_algorithm.c -lm -lpigpio -L/usr/lib/ which gives me the following :
/usr/bin/ld: /tmp/cc6ad5oo.o:(.bss+0x3c18): multiple definition of `someVar1'; /tmp/ccaydPyq.o:(.bss+0x24918): first defined here
/usr/bin/ld: /tmp/cc6ad5oo.o:(.bss+0x3c1c): multiple definition of `someVar2'; /tmp/ccaydPyq.o:(.bss+0x2491c): first defined here
and same errors for the rest of the variables declared in the header file. Does anyone have any idea what is causing the errors.
/usr/bin/ld: /tmp/cc6ad5oo.o:(.bss+0x3c18): multiple definition of `someVar1'; /tmp/ccaydPyq.o:(.bss+0x24918): first defined here
/usr/bin/ld: /tmp/cc6ad5oo.o:(.bss+0x3c1c): multiple definition of `someVar2'; /tmp/ccaydPyq.o:(.bss+0x2491c): first defined here
you have to make sure, the same code won't be included multiple times.
You can do this by embedding the header file code in #ifndef #define #endif macros. These are called include guards
The rest of your code seems to be working fine.
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.
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
How do I make a C function visible for functions only in other certains .c files?
Let's suppose I have a foo1 function wich calls other foo2 function (in differents .c files) and I want to call foo1 from my main function, but I want foo2 to be invisible for any function other than foo1, like this:
/**
foo1.c
*/
void foo1()
{
if (condition_is_true){
foo2();
}
}
/**
foo2.c
*/
#include <stdio.h>
void foo2()
{
printf("Hello world!\n");
}
/**
main.c
*/
void foo1(void);
void foo2(void);
int main()
{
foo1();
foo2(); /*unresolved external*/
}
And when compiling
$ cc -omain main.c foo1.c foo2.c
I want the linker to complain "undefined reference to `foo2'".
Usually, if you want to make a function in one .c source code file visible in another .c source file, you place the definition of that function into a .h file and include it into the .c file you want it visible in. For example:
file foo1.c
int somefunc1(some parameters)
{
Do some stuff.
}
file foo1.h
int somefunc1(some parameters);
file foo2.c
#include "foo1.h"
int foo2(Some parameters)
{
Do some stuff.
foo1(asdfasdf)
Do some more stuff.
}
That is generally what you do. However, what you are asking for is the exact opposite. I'm not sure why you want an undefined reference when the linker runs, but the way that you have set your compile, those files will get passed to the linker. So the only thing that you can do is not have foo2.c on the file list. If you are using something from one of the main libraries, it still gets linked in even if you don't specify the include file. For instance:
$$$ ->more test3.c
int main(void)
{
printf("hello world\n");
return(0);
}
$$$ ->clang -std=c11 -Wall -Wextra -o test3 test3.c
test3.c:8:5: warning: implicitly declaring library function 'printf' with type 'int (const char *, ...)'
printf("hello world\n");
^
test3.c:8:5: note: please include the header <stdio.h> or explicitly provide a declaration for 'printf'
1 warning generated.
So what you are asking for I don't really think can or should be done.
I need to include file_1.c into main.c. In file_1.c, I currently have multiple functions. If I want to call these functions in main.c, what do I need to do? I have #include"file_1.c" in my main program.
Use standard approach by making header file
#include"file_1.h"
you will have to compile this "file_1.c" together with main.c and make one executable
because function calls are need in run time.
Try this :
create a header file file_1.h
#ifndef _FILE_H
#define _FILE_H
void foo(int );
#endif
give all the declaraion of function and struct definitions (if any) or any global variables
then in file_1.c will contain actual defintion of function
//file_1.c
#include "file_1.h"
#include <stdio.h>
void foo(int x)
{
printf("%d\t",x);
}
//main.c
#include "file_1.h"
int main()
{
int x=10;
foo(x);
return 0;
}
include header file file_1.h in both (main.c and file_1.c) the c files
In gcc
gcc -Wall main.c file_1.c -o myexe.out
Why do you think you need to do this?
Normally you would add the declaration of functions in file_1.c into file_1.h and include that in main.c.
When you link the program, you just need to include both main.c and file_1.c (which then includes the definitions of the functions) on the command line.
// File foo1.c :
#include <stdio.h> // once
void foo1(void);
void foo1(void){
puts("foo1");
}
// File foo2.c :
#include <stdio.h> // again
void foo2(void);
void foo2(void){
puts("foo2");
}
// File foomain.c :
#include <stdio.h> // yet again
void foo1(void); // again
void foo2(void); // again
int main(void){
foo1();
foo2();
puts("foomain");
return 0;
}
// create object files
gcc -fPIC foo1.c -o foo1.o // 1 stdio.h
gcc -fPIC foo2.c -o foo2.o // 1 stdio.h
// create shared library
gcc -fPIC -shared foo1.o foo2.o -o foo.so // foo.so contains stdio.h 2 times ?
// build entire program
gcc foo.so foomain.c -o foomain // foomain contains 1 stdio.h plus the 2 from foo.so ?
Why does the entire program contain 3 stdio.h ? Seems redundant, why not just 1 ? Shouldn't the compiler need only 1 ?
It makes sense for the object files to contain a prototype but why do they have to be specified again in foomain.c ? Shouldn't the compiler know they are already specified in foo.so ?
That's because each file is compiled separately, so each time the compiler should know the signatures of all functions used to perform compile-time checks. So, each file has to contain all declarations used, which are included by the preprocessor before the file is compiled.
If you look at the top of most header files they have an include guard to stop double inclusion.
#ifndef FOO
#define FOO
#endif
See Include Guard for more information.
The #include lines are not actually a part of the compiler, but the C preprocessor.
What the preprocessor does with #include lines is to actually include the file into the source, and creates a new temporary file containing the contents of your file with the #include line replaced by the contents of the file being included.
You don't actually need the include file at all, if all you are doing is calling functions. You might get warnings about the functions not being declared, but those can be adding the prototypes for those functions yourself. For example, in your main source file you only use puts, instead of including <stdio.h> you can add a prototype like this:
int puts(const char *s);
However, <stdio.h> also defines some structures (like the FILE structure) and declares some variables (like stdout) and if you use any of those you need the header file as well.
You can use include guards as #Jeff suggested or just put #pragma once at the top of each header.