Math function compiler linking error - c

The following code compiles on other systems, but not on my Ubuntu 12.04 64bit guest in Virtualbox 4.3.10 on a Windows 7 64bit host.
hello.c
#include "header.h"
int main(int argc, char *argv[]){
int i;
for(i=0; i<argc; i++)
printf("%s\n", argv[i]);
double x;
x = testfunction();
printf("%f \n", x);
return 0;
}
hello2.c
#include "header.h"
double testfunction ()
{
int i = 1;
double j = 0;
for(i=0; i<1000000; i++)
j += sin(i/M_PI);
return j;
}
header.h
#include <math.h>
#include <stdio.h>
double testfunction();
When I attempt to compile using
gcc -lm -o hello hello.c hello2.c
I receive the error
/tmp/ccirukEU.o: In function testfunction':
hello2.c:(.text+0x33): undefined reference tosin'
collect2: ld returned 1 exit status
The error remains even if I include math.h directly in hello2.c. Calculating sin(2/M_Pi) rather than sin(i/M_Pi) removes the error, possibly because gcc then works out the sine itself rather than using the math library.

Use -lm in the end, as in:
gcc -o hello hello.c hello2.c -lm
This ensures that the linker can realize that there are dependencies missing. Using -lm in the beginning is known to raise problems, because by the time the linker looks at the math library, it hasn't looked at your code yet, so there are no dependencies unresolved.

Related

How to pass a string into a system call in xv6

I have to pass a string into a system call in xv6, so I know I have to use argstr(), my question lies with implementing it.
Here is what I have added to sysproc.c:
int sys_hello(char **str)
{
int n = 15;
argstr(n, **str);
for (int i = 0; i < n; i++){
cprintf("%c testplzprint",str[i]);
}
cprintf("Hello World\n");
return 0;
}
I am calling it from testcase.c:
#include "types.h"
#include "stat.h"
#include "user.h"
int main(void)
{
for (int i = 0; i < 5; i++){
hello("itworks");
}
exit();
}
I first implemented it without the testcase and argstr() and just printed hello and it worked well. I'm guessing my problem lies in how I am using argstr(). I really appreciate any help!
Update: sorry for not providing output, here it is right now.
js9313rr#smaug:/tmp/.x2go-js9313rr/media/disk/_cygdrive_C_Users_real0_Desktop_school_SPRING1_352/CSIS352/OS/OS lab 4/xv6-public-master$ make
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie -no-pie -c -o sysproc.o sysproc.c
sysproc.c: In function \u2018sys_hello\u2019:
sysproc.c:97:13: error: passing argument 2 of \u2018argstr\u2019 makes pointer from integer without a cast [-Werror=int-conversion]
argstr(n, **str);
^
In file included from sysproc.c:3:0:
defs.h:154:17: note: expected \u2018char **\u2019 but argument is of type \u2018char\u2019
int argstr(int, char**);
^~~~~~
cc1: all warnings being treated as errors
<builtin>: recipe for target 'sysproc.o' failed
make: *** [sysproc.o] Error 1
make the hello prototype clear:
Do you want a array of strings ou just a string?
Your sys_hello prototype is wrong, it should be sys_hello(void).
Here an example with an hello syscall taking one string as parameter:
int sys_hello(void)
char *string;
if(argstr(0, &string) < 0){
return -1;
}
cprintf(string);
return 0;

Why even though linking is finished correctly, i get undefined reference error?

I'm trying to learn c and I implemented a bubblesort function and i decided It would be better idea if i made a library that will contain various sorting algorithms, so I compiled my code with this:
gcc -shared -fPIC -o bin/bsort.o sort/Bubblesort.c
my bubblesort.c is working (and not related to question at all and there is nothing other than bubblesort function there):
// Licensed under public domain with no warranty
void bubblesort(int* array) {
//implemention goes here
}
my sort.h file:
void bubblesort(int* array);
my nsort.c
#include "sort/sort.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int main() {
int* sortthis = malloc(1000*sizeof(int));
for(int i = 0; i < 1000; i++) {
*(sortthis+i) = random(); //random int is defined somewhere else
}
bubblesort(sortthis);
for(int i = 0; i < 90; i++) {
printf("%d ",*(sortthis+i));
}
free(sortthis);
return 0;
}
my script that i use to compile:
gcc -shared -fPIC -o bin/bsort.o sort/Bubblesort.c
gcc nsort.c sort/sort.h -Lbin/bsort.o -lm -o demo.elf
what could be i'm doing wrong, i tried various things but it didn't work, i kept getting following error:
/usr/bin/ld: /tmp/ccxhd5zd.o: in function `main':
nsort.c:(.text+0x23): undefined reference to `bubblesort'
collect2: error: ld returned 1 exit status
gcc --version (just in case if there is a bug in this version):
gcc (Debian 10.2.1-6) 10.2.1 20210110
You don't put -L before the .o file. -L is for adding directories that -l searches for libraries.
To link with an object file, just add it as an ordinary file argument.
You also don't need to include header files in the compiler arguments. The compiler reads them when it sees #include.
gcc nsort.c bin/bsort.o -lm -o demo.elf

Trouble compiling c gsl library from max terminal

I have a c script
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
int main(void)
{
const gsl_rng_type * T;
gsl_rng * r;
int i;
double a,b;
double num;
a=10;
b=7.2;
gsl_rng_env_setup();
T=gsl_rng_default;
r=gsl_rng_alloc (T);
for(i=0; i<10; i++)
{
num = gsl_ran_gamma(r,a,b);
printf("%.8f \n",num);
}
gsl_rng_free(r);
return 0;
}
Which I have successfully compiled on a linux machine. I want to use the gsl library for other applications on my mac. So I first installed gsl using homebrew which seemed to be successful. To make sure everything was working right I tried to compile and run this script as follows
[ACC-259-imac:GDSC Gene Expression Modeling jmannhei$ gcc -Wall gamma.c -o gamma.out -lm -lgsl -lgslcblas
which resulted in the following output
gamma.c:5:10: fatal error: 'gsl/gsl_rng.h' file not found
#include <gsl/gsl_rng.h>
^
1 error generated.
Which is exactly how I compiled it on Linux so I am not sure what is awry as I have compile c scripts in the past using this format from terminal on a mac before. My guess is it is not linking properly but I am not sure what I need to do to fix it. Thanks
Find your header file directory with brew list gsl or locate gsl/gsl_rng.h then tell your compiler where the headers are. I would need the following, for example,
gcc -Wall -I/usr/local/Cellar/gsl/1.16/include/ gamma.c -o gamma.out -lm -lgsl -lgslcblas

GCC Error but VS no error

When I compile the below program it is giving me this error.
/tmp/ccwr6gsJ.o: In function 'main':
main.cL(.text+0xa): undefined reference to 'example'
collect2: error: Id returned 1 exit status
Main.c:
#include <stdio.h>
#include "includes.h"
int main()
{
int exampleInt = example();
return 0;
}
includes.h:
int example();
includes.c:
#include "includes.h"
int example()
{
int i = 3;
return i;
}
It seems to work in Visual Studio but not on GCC on Linux
This is very likely a build error, i.e. you're calling the compiler on the wrong set(s) of files, and/or not doing a linking step.
Try:
$ gcc -o myprog main.c example.c
Note that a mere #include in a C file does not in any way tell the compiler to compile more C files.

C Undefined reference

I have the following code:
main.c
#include "checksum.h"
void main()
{
char *Buf ="GPGGA204502.005106.9813N11402.2921W1090.91065.02M-16.27M";
checksum(Buf);
}
checksum.c
#include <stdio.h>
#include <string.h>
checksum(char *Buff)
{
int i;
unsigned char XOR;
unsigned long iLen = strlen(Buff);
printf("Calculating checksum...\n");
for (XOR = 0, i = 0; i < iLen; i++)
XOR ^= (unsigned char)Buff[i];
printf("%X \n",XOR);
}
checksum.h
#ifndef CHECKSUM_H_INCLUDED
#define CHECKSUM_H_INCLUDED
void checksum(char *Buff);
#endif
When compiling I get the following error:
/tmp/ccFQS7Ih.o: In function `main':
main.c:(.text+0x18): undefined reference to `checksum'
collect2: ld returned 1 exit status
I can't figure out what the problem is?
You are compiling only one file not both. More precisely, you are not linking the files together.
I don't know your compiler, but with gcc, it would be something like this:
gcc -c main.c <-- compile only
gcc -c checksum.c <-- compile only
gcc main.o checksum.o <-- link the two
Edit: To automate this process, take a look at the make program which reads Makefiles.
You could also try
gcc -o program.out main.c checksum.c which will compile and link both files together
I think: in checksum.c, you should include checksum.h.

Resources