BCM2835 installed but giving undefined references - c

So I installed BCM2835 but when I'm trying to compile a .c file with "gcc -c main main.c" it gives the following errors. I have no idea on how to compile linux btw, just follow stuff on the internet.
/tmp/ccSVwHkt.o: In function `main':
main.c:(.text+0x14): undefined reference to `bcm2835_init'
main.c:(.text+0x3c): undefined reference to `bcm2835_gpio_fsel'
main.c:(.text+0x48): undefined reference to `bcm2835_gpio_write'
main.c:(.text+0x50): undefined reference to `bcm2835_delay'
main.c:(.text+0x5c): undefined reference to `bcm2835_gpio_write'
main.c:(.text+0x64): undefined reference to `bcm2835_delay'
collect2: ld returned 1 exit status
This is the content of main.c (copied from Google code)
/*
* main.c
*
* Created on: 23-jun.-2013
* Author: Andreas Backx
*/
#include <bcm2835.h>
// Blinks on RPi Plug P1 pin 11 (which is GPIO pin 17)
#define PIN RPI_GPIO_P1_11
int main(int argc, char **argv)
{
// If you call this, it will not actually access the GPIO
// Use for testing
// bcm2835_set_debug(1);
if (!bcm2835_init())
return 1;
// Set the pin to be an output
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);
// Blink
while (1)
{
// Turn it on
bcm2835_gpio_write(PIN, HIGH);
// wait a bit
bcm2835_delay(500);
// turn it off
bcm2835_gpio_write(PIN, LOW);
// wait a bit
bcm2835_delay(500);
}
bcm2835_close();
return 0;
}

gcc -c main main.c doesn't make sense given the output you're getting. That said, if it's really what you're doing, you need to change it:
gcc -o main main.c
You'll likely still get the "undefined symbol" errors from the linker, since you're not linking with whatever library defines those symbols. A quick check of the examples at the site you linked shows that you need to link with the bcm2835 library:
gcc -o main main.c -lbcm2835
You may also need to add a -L flag if you installed the library somewhere where gcc doesn't know to look for it.

I'll tell you an easier option so that you don't have to worry about writing this command every time.
If you are working on Geany, go to the section, then . There you will see that you are using this command
to compile -> gcc -Wall -c "% f".
Put it in place gcc -Wall -c "% f" -lbcm2835.
And in the line -> gcc -Wall -o "% e" "% f" -lbcm2835.
And in the line -> sudo "./%e"
And press ok.
Now everything will work ;)

Related

math.h's fmod function giving error when compiling in "C" [duplicate]

Sample code for fmod:
#include <stdio.h>
#include <math.h>
int main(void)
{
double x = 0.14527, y = 3.14159;
printf("fmod(x, y) = %.6lf\n", fmod(x, y));
return 0;
}
Compiling:
$ gcc main.c -o main
I get
/tmp/ccztJO01.o: In function `main':
main.c:(.text+0x4d): undefined reference to `fmod'
collect2: ld returned 1 exit status
Then I found this in Google:
$ gcc -lm main.c -o main
Why should I use -lm, what is it exactly? From where I can get more information about gcc in detail?
-lm is simply telling it to link libm, which contains all the floating point math routines, including (no surprise here) fmod.
When I input gcc -lm main.c -o main I still get a linker error. I need to write gcc main.c -lm -o main for it work right. If it's working for you the other way, that's a bit odd. I understand that the linker will find the symbol declared in main.c (i.e. double fmod(double,double)), but only resolve it if it finds its definition later on (i.e. in libm.a).
Long story short, the libraries must be placed (at least once) "to the right of" the place where they are used.
It's not the compiler, but the linker, ld, that is complaining. It cannot find the routine fmod in your program. You have to tell it to link with math library libm with the -l flag.
[Much] more info: GCC, the GNU Compiler Collection.

How can I call a specific function at program start using MinGW compiler? [duplicate]

How to change the entry point of a C program compiled with gcc ?
Just like in the following code
#include<stdio.h>
int entry() //entry is the entry point instead of main
{
return 0;
}
It's a linker setting:
-Wl,-eentry
the -Wl,... thing passes arguments to the linker, and the linker takes a -e argument to set the entry function
You can modify your source code as:
#include<stdio.h>
const char my_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
int entry() //entry is the entry point instead of main
{
exit(0);
}
The ".interp" section will let your program able to call external shared library.
The exit call will make your entry function to exit program instead of return.
Then build the program as a shared library which is executable:
$ gcc -shared -fPIC -e entry test_main.c -o test_main.so
$ ./test_main
If you are on a system that provides GNU Binutils (like Linux),
you can use the objcopy command
to make an arbitrary function the new entry point.
Suppose a file called program.c containing the entry function:
$ cat > program.c
#include <stdio.h>
int entry()
{
return 0;
}
^D
You first compile it using -c to generate a relocatable object file:
$ gcc -c program.c -o program.o
Then you redefine entry to be main:
$ objcopy --redefine-sym entry=main program.o
Now use gcc to compile the new object file:
$ gcc program.o -o program
NOTE: If your program already has a function called main, before step 2, you can perform a separate objcopy invocation:
objcopy --redefine-sym oldmain=main program.o
Minimal runnable example and notes on other answers
main.c
#include <stdio.h>
#include <stdlib.h>
int mymain(void) {
puts("hello");
exit(0);
}
compile and run:
gcc -nostartfiles -Wl,--entry=mymain -o main.out main.c
# or -Wl,-emymain
./main.out 1 2 3
The notes:
without -nostartfiles, the link fails with:
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
presumably because the glibc setup code that runs before main in _start normally calls main.
command line arguments are not setup for you, presumably because they would be setup by the glibc code that runs before main, so trying to use them prints undefined values. I haven't found a method that works for them.
Tested in Ubuntu 20.10.

naming main function something other than main [duplicate]

How to change the entry point of a C program compiled with gcc ?
Just like in the following code
#include<stdio.h>
int entry() //entry is the entry point instead of main
{
return 0;
}
It's a linker setting:
-Wl,-eentry
the -Wl,... thing passes arguments to the linker, and the linker takes a -e argument to set the entry function
You can modify your source code as:
#include<stdio.h>
const char my_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
int entry() //entry is the entry point instead of main
{
exit(0);
}
The ".interp" section will let your program able to call external shared library.
The exit call will make your entry function to exit program instead of return.
Then build the program as a shared library which is executable:
$ gcc -shared -fPIC -e entry test_main.c -o test_main.so
$ ./test_main
If you are on a system that provides GNU Binutils (like Linux),
you can use the objcopy command
to make an arbitrary function the new entry point.
Suppose a file called program.c containing the entry function:
$ cat > program.c
#include <stdio.h>
int entry()
{
return 0;
}
^D
You first compile it using -c to generate a relocatable object file:
$ gcc -c program.c -o program.o
Then you redefine entry to be main:
$ objcopy --redefine-sym entry=main program.o
Now use gcc to compile the new object file:
$ gcc program.o -o program
NOTE: If your program already has a function called main, before step 2, you can perform a separate objcopy invocation:
objcopy --redefine-sym oldmain=main program.o
Minimal runnable example and notes on other answers
main.c
#include <stdio.h>
#include <stdlib.h>
int mymain(void) {
puts("hello");
exit(0);
}
compile and run:
gcc -nostartfiles -Wl,--entry=mymain -o main.out main.c
# or -Wl,-emymain
./main.out 1 2 3
The notes:
without -nostartfiles, the link fails with:
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
presumably because the glibc setup code that runs before main in _start normally calls main.
command line arguments are not setup for you, presumably because they would be setup by the glibc code that runs before main, so trying to use them prints undefined values. I haven't found a method that works for them.
Tested in Ubuntu 20.10.

Undefined reference to... when linking library header

I'm trying to compile a C program that uses libvncserver but no matter what I do I keep getting undefined reference errors, the library I'm having troubles with is rfb/rfb.h.
vnc.c code (copied from here):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rfb/rfb.h>
#define WIDTH 640
#define HEIGHT 480
#define BPP 4
/* 15 frames per second (if we can) */
#define PICTURE_TIMEOUT (1.0/15.0)
/*
* throttle camera updates
*/
int TimeToTakePicture() {
static struct timeval now={0,0}, then={0,0};
double elapsed, dnow, dthen;
gettimeofday(&now,NULL);
dnow = now.tv_sec + (now.tv_usec /1000000.0);
dthen = then.tv_sec + (then.tv_usec/1000000.0);
elapsed = dnow - dthen;
if (elapsed > PICTURE_TIMEOUT)
memcpy((char *)&then, (char *)&now, sizeof(struct timeval));
return elapsed > PICTURE_TIMEOUT;
}
/*
* simulate grabbing a picture from some device
*/
int TakePicture(unsigned char *buffer)
{
static int last_line=0, fps=0, fcount=0;
int line=0;
int i,j;
struct timeval now;
/*
* simulate grabbing data from a device by updating the entire framebuffer
*/
for(j=0;j<HEIGHT;++j) {
for(i=0;i<WIDTH;++i) {
buffer[(j*WIDTH+i)*BPP+0]=(i+j)*128/(WIDTH+HEIGHT); /* red */
buffer[(j*WIDTH+i)*BPP+1]=i*128/WIDTH; /* green */
buffer[(j*WIDTH+i)*BPP+2]=j*256/HEIGHT; /* blue */
}
buffer[j*WIDTH*BPP+0]=0xff;
buffer[j*WIDTH*BPP+1]=0xff;
buffer[j*WIDTH*BPP+2]=0xff;
}
/*
* simulate the passage of time
*
* draw a simple black line that moves down the screen. The faster the
* client, the more updates it will get, the smoother it will look!
*/
gettimeofday(&now,NULL);
line = now.tv_usec / (1000000/HEIGHT);
if (line>HEIGHT) line=HEIGHT-1;
memset(&buffer[(WIDTH * BPP) * line], 0, (WIDTH * BPP));
/* frames per second (informational only) */
fcount++;
if (last_line > line) {
fps = fcount;
fcount = 0;
}
last_line = line;
fprintf(stderr,"%03d/%03d Picture (%03d fps)\r", line, HEIGHT, fps);
/* success! We have a new picture! */
return (1==1);
}
/*
* Single-threaded application that interleaves client servicing with taking
* pictures from the camera. This way, we do not update the framebuffer
* while an encoding is working on it too (banding, and image artifacts).
*/
int main(int argc,char** argv)
{
long usec;
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,WIDTH,HEIGHT,8,3,BPP);
if(!server)
return 0;
server->desktopName = "Live Video Feed Example";
server->frameBuffer=(char*)malloc(WIDTH*HEIGHT*BPP);
server->alwaysShared=(1==1);
/* Initialize the server */
rfbInitServer(server);
/* Loop, processing clients and taking pictures */
while (rfbIsActive(server)) {
if (TimeToTakePicture())
if (TakePicture((unsigned char *)server->frameBuffer))
rfbMarkRectAsModified(server,0,0,WIDTH,HEIGHT);
usec = server->deferUpdateTime*1000;
rfbProcessEvents(server,usec);
}
return(0);
}
Compiler output:
sudo gcc -g -Wall -Wextra -O2 vnc.c
/tmp/cc7dpMCs.o: In function `main':
/home/arcm/Projects/c/vnc.c:77: undefined reference to `rfbGetScreen'
/home/arcm/Projects/c/vnc.c:84: undefined reference to `rfbInitServerWithPthreadsAndZRLE'
/home/arcm/Projects/c/vnc.c:91: undefined reference to `rfbProcessEvents'
/home/arcm/Projects/c/vnc.c:86: undefined reference to `rfbIsActive'
/home/arcm/Projects/c/vnc.c:89: undefined reference to `rfbMarkRectAsModified'
collect2: error: ld returned 1 exit status
I've got libvncserver0 and libvncserver-dev installed and i'm using ubuntu 14.04.
I tried:
sudo gcc -g -Wall -Wextra -O2 vnc.c -lm
sudo gcc -g -Wall -Wextra -O2 vnc.c -ldl
sudo gcc -g -Wall -Wextra -O2 -ldl vnc.c
sudo gcc -g -Wall -Wextra -O2 -I/usr/include/rfb -L/usr/include/rbf/rfb.h vnc.c
sudo gcc -g -Wall -Wextra -O2 -I/usr/include/rfb vnc.c
sudo gcc -g -Wall -Wextra -O2 -L/usr/include/rbf/rfb.h vnc.c
sudo gcc -g -Wall -Wextra -O2 /usr/include/rbf/rfb.h vnc.c
sudo gcc -g -Wall -Wextra -O2 -L/usr/include/rbf/rfb.h -ldl vnc.c
But I get the same errors everytime. What am I doing wrong and how can I fix it?
You don't "link" a library header, you include it so the compiler sees the library's declarations at compile time and knows that rfbGetScreen() is a function that takes so-and-so many arguments of this-and-that type and returns a rfbScreenInfoPtr. How it does this (the definition of the function) is not important to the compiler. It just adds a reference to that function, which is left for the linker to resolve. (Note the vocabulary here.)
You link your compiled code to the library binary. This is done by the linker, in a different (and later) step that just happens to be supported by the same frontend as compiling your source (gcc). In this step, any of the library functions that your code actually uses (references) are resolved by linking them in from the specified libraries.
This here...
sudo gcc -g -Wall -Wextra -O2 vnc.c
...links only the standard library and runtime, as there are no specific linking instructions in there.
This here...
-L/usr/include/rbf/rfb.h
...is nonsense, as -L is for giving directories where library binaries should be looked for (and is not necessary if the library in question is installed in the standard location).
The actual link instruction is -l. If you state -lfoo, then the library libfoo is searched for any undefined references.
This here...
-ldl
...is linking libdl, and from that you should be able to deduce that...
-lvncserver
...is what you're looking for (assuming that <rfb/rfb.h> actually does refer to libvncserver, which I don't know).
Note that the linker is processing libraries in the sequence they are given on the command line, so you need to state -lvncserver after vnc.c, because only then does the linker know which undefined references it ought to be looking for in libvncserver.
And never, ever run a compiler as sudo. Why in {.....}'s name do you think this would be necessary?

gcc gives error while using fmod()

Sample code for fmod:
#include <stdio.h>
#include <math.h>
int main(void)
{
double x = 0.14527, y = 3.14159;
printf("fmod(x, y) = %.6lf\n", fmod(x, y));
return 0;
}
Compiling:
$ gcc main.c -o main
I get
/tmp/ccztJO01.o: In function `main':
main.c:(.text+0x4d): undefined reference to `fmod'
collect2: ld returned 1 exit status
Then I found this in Google:
$ gcc -lm main.c -o main
Why should I use -lm, what is it exactly? From where I can get more information about gcc in detail?
-lm is simply telling it to link libm, which contains all the floating point math routines, including (no surprise here) fmod.
When I input gcc -lm main.c -o main I still get a linker error. I need to write gcc main.c -lm -o main for it work right. If it's working for you the other way, that's a bit odd. I understand that the linker will find the symbol declared in main.c (i.e. double fmod(double,double)), but only resolve it if it finds its definition later on (i.e. in libm.a).
Long story short, the libraries must be placed (at least once) "to the right of" the place where they are used.
It's not the compiler, but the linker, ld, that is complaining. It cannot find the routine fmod in your program. You have to tell it to link with math library libm with the -l flag.
[Much] more info: GCC, the GNU Compiler Collection.

Resources