This question already has answers here:
Ordering of object files and libraries in static linking
(1 answer)
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Closed 3 years ago.
I try to Compile this Simple Lua Tutorial Program:
#include <stdio.h>
#include <string.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main (void) {
char buff[256];
int error;
lua_State *L = lua_open(); /* opens Lua */
luaopen_base(L); /* opens the basic library */
luaopen_table(L); /* opens the table library */
luaopen_io(L); /* opens the I/O library */
luaopen_string(L); /* opens the string lib. */
luaopen_math(L); /* opens the math lib. */
while (fgets(buff, sizeof(buff), stdin) != NULL) {
error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
lua_pcall(L, 0, 0, 0);
if (error) {
fprintf(stderr, "%s", lua_tostring(L, -1));
lua_pop(L, 1); /* pop error message from the stack */
}
}
lua_close(L);
return 0;
}
With the Following Command:
gcc -I/usr/include/lua50 -L/usr/lib/liblua50.a -llua50 luainterpret.c
So the Headers are Linked and Library Binary should also be Linked right?
However i get the following undefined References:
/tmp/ccA3kOUt.o: In function `main':
luainterpret.c:(.text+0x1b): undefined reference to `lua_open'
luainterpret.c:(.text+0x31): undefined reference to `luaopen_base'
luainterpret.c:(.text+0x40): undefined reference to `luaopen_table'
luainterpret.c:(.text+0x4f): undefined reference to `luaopen_io'
luainterpret.c:(.text+0x5e): undefined reference to `luaopen_string'
luainterpret.c:(.text+0x6d): undefined reference to `luaopen_math'
luainterpret.c:(.text+0xa1): undefined reference to `luaL_loadbuffer'
luainterpret.c:(.text+0xc3): undefined reference to `lua_pcall'
luainterpret.c:(.text+0xf6): undefined reference to `lua_tostring'
luainterpret.c:(.text+0x11f): undefined reference to `lua_settop'
luainterpret.c:(.text+0x152): undefined reference to `lua_close'
collect2: error: ld returned 1 exit status
I checked the /usr/lib/liblua50.a file with nm and the Functions above are indeed there! Why is gcc then not able to find said Functions?
Can someone tell me what im doing wrong?
Instead of putting the library before the source file (which makes use of the functions present in the library), try putting it afterwards, like
gcc -I/usr/include/lua50 -L/usr/lib/liblua50.a luainterpret.c -llua50
From the online gcc manual
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
Related
I am using dlsym to look up symbols in my program, but it always returns NULL, which I am not expecting. According to the manpage, dlsym may return NULL if there was an error somehow, or if the symbol indeed is NULL. In my case, I am getting an error. I will show you the MCVE I have made this evening.
Here is the contents of instr.c:
#include <stdio.h>
void * testing(int i) {
printf("You called testing(%d)\n", i);
return 0;
}
A very simple thing containing only an unremarkable example function.
Here is the contents of test.c:
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
typedef void * (*dltest)(int);
int main(int argc, char ** argv) {
/* Declare and set a pointer to a function in the executable */
void * handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
dlerror();
dltest fn = dlsym(handle, "testing");
if(fn == NULL) {
printf("%s\n", dlerror());
dlclose(handle);
return 1;
}
dlclose(handle);
return 0;
}
As I step through the code with the debugger, I see the dlopen is returning a handle. According to the manpage, If filename is NULL, then the returned handle is for the main program. So if I link a symbol called testing into the main program, dlsym should find it, right?
Here is the way that I am compiling and linking the program:
all: test
instr.o: instr.c
gcc -ggdb -Wall -c instr.c
test.o: test.c
gcc -ggdb -Wall -c test.c
test: test.o instr.o
gcc -ldl -o test test.o instr.o
clean:
rm -f *.o test
And when I build this program, and then do objdump -t test | grep testing, I see that the symbol testing is indeed there:
08048632 g F .text 00000020 testing
Yet the output of my program is the error:
./test: undefined symbol: testing
I am not sure what I am doing wrong. I would appreciate if someone could shed some light on this problem.
I don't think you can do that, dlsym works on exported symbols. Because you're doing dlsym on NULL (current image), even though the symbols are present in the executable ELF image, they're not exported (since it's not a shared library).
Why not call it directly and let the linker take care of it? There's no point in using dlsym to get symbols from the same image as your dlsym call. If your testing symbol was in a shared library that you either linked against or loaded using dlopen then you would be able to retrieve it.
I believe there's also a way of exporting symbols when building executables (-Wl,--export-dynamic as mentioned in a comment by Brandon) but I'm not sure why you'd want to do that.
I faced the similar issue in my code.
I did the following to export symbols
#ifndef EXPORT_API
#define EXPORT_API __attribute__ ((visibility("default")))
#endif
Now for each of the function definition I used the above attribute.
For example the earlier code was
int func() { printf(" I am a func %s ", __FUNCTION__ ) ;
I changed to
EXPORT_API int func() { printf(" I am a func %s ", __FUNCTION__ ) ;
Now it works.
dlsym gives no issues after this.
Hope this works for you as well.
I am trying to use lessfs and learning how it uses mhash to produce its cryptographic fingerprints, so I am taking a look at mhash to see how it handles the hashing algorithms, so I am trying to run some of the examples provided in the program, but I am running into complications and errors
The Mhash example that I was trying to solve is found here: http://mhash.sourceforge.net/mhash.3.html (or below)
#include <mhash.h>
#include <stdio.h>
int main()
{
char password[] = "Jefe";
int keylen = 4;
char data[] = "what do ya want for nothing?";
int datalen = 28;
MHASH td;
unsigned char *mac;
int j;
td = mhash_hmac_init(MHASH_MD5, password, keylen,
mhash_get_hash_pblock(MHASH_MD5));
mhash(td, data, datalen);
mac = mhash_hmac_end(td);
/*
* The output should be 0x750c783e6ab0b503eaa86e310a5db738
* according to RFC 2104.
*/
printf("0x");
for (j = 0; j < mhash_get_block_size(MHASH_MD5); j++) {
printf("%.2x", mac[j]);
}
printf("\n");
exit(0);
}
But I get the following errors:
mhash.c.text+0x6c): undefined reference to `mhash_get_hash_pblock'
mhash.c.text+0x82): undefined reference to `mhash_hmac_init'
mhash.c.text+0x9c): undefined reference to `mhash'
mhash.c.text+0xa8): undefined reference to `mhash_hmac_end'
mhash.c.text+0xf9): undefined reference to `mhash_get_block_size'
collect2: error: ld returned 1 exit status
This is a linker error — ld is the linker program on Unix systems. The linker is complaining because you're using library functions (mhash_get_hash_pblock, etc.) but you didn't provide a definition for them.
The preprocessor directive #include <mhash.h> declares functions (and types, etc.) from the mhash library. That's good enough to compile your program (produce a .o file) but not to link it (to produce an executable): you also need to define these functions.
Add -lmhash at the end of your compilation command line. This instructs the linker that it can look for functions in the library libmhash.a on its search path; at run time, the functions will be loaded from libmhash.so on the search path. Note that libraries must come on the command line after they're used: the linker builds up a link of required functions, which need to be provided by a subsequent argument.
gcc -o myprogram myprogram.c -lmhash
This question already has answers here:
Undefined reference to `pow' and `floor'
(6 answers)
Closed 9 years ago.
I wrote this function
int *constructST(int arr[], int n)
{
// Allocate memory for segment tree
int x = (int)(ceil(log2(n))); //Height of segment tree
int max_size = 2*(int)pow(2, x) - 1; //Maximum size of segment tree
int *st = malloc(max_size*sizeof(int));
// Fill the allocated memory st
constructSTUtil(arr, 0, n-1, st, 0);
// Return the constructed segment tree
return st;
}
and I have included the following libraries math.h ,stdlib.h, stdio.h but I get the following error
/tmp/ccg4X72c.o: In function `constructST':
tree.c:(.text+0x3f4): undefined reference to `log2'
tree.c:(.text+0x40b): undefined reference to `ceil'
tree.c:(.text+0x433): undefined reference to `pow'
collect2: error: ld returned 1 exit status
Any help why I am getting this error though I have included the math.h .
Including <math.h> ensures that your program knows the function prototypes for these functions, so it can tell that you're calling them correctly, but it doesn't actually link the library code in to them. For that you will have to add the right linker flag when you build it, usually -lm:
gcc -o myprog myprog.c -lm
This question already has answers here:
Error when connecting to Postgres database in C - using libpq-fe.h
(2 answers)
Closed 9 years ago.
I have the following code:
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
int main(int argc, char* argv[])
{
//Start connection
PGconn* connection = PQconnectdb("host=webcourse.cs.nuim.ie dbname=cs621 sslmode=require user=ggales password=1234");
if (PQstatus(connection) ==CONNECTION_BAD)
{
printf("Connection error\n");
PQfinish(connection);
return -1; //Execution of the program will stop here
}
printf("Connection ok\n");
//End connection
PQfinish(connection);
printf("Disconnected\n");
return 0;
}
When I run it, I get the following error:
/tmp/cc73kO0N.o: In function `main':
main.c:(.text+0x15): undefined reference to `PQconnectdb'
main.c:(.text+0x25): undefined reference to `PQstatus'
main.c:(.text+0x40): undefined reference to `PQfinish'
main.c:(.text+0x5d): undefined reference to `PQfinish'
collect2: error: ld returned 1 exit status
This is strange, as PQconnectdb etc are all functions that are defined in libpq-fe.h, which I have already included in the code.
Any help would be great thanks.
#include <libpq-fe.h> does not link to the library, it only includes information about the functions and data types that the library provides.
You must tell the linker where the references that are declared in libpq-fe.h can actually be found.
If you are using a Makefile to compile you code you should add -lpq to your LDFLAGS or linking command.
Post the command you are running to compile to give us more information.
I am working from a book: TCP/IP Sockets in C and its website code.
I am trying to build a client and server based on those files. My make gives lots of
error related to not being able to find functions from DieWithMessage.c
Here it is:
#include <stdio.h>
#include <stdlib.h>
#include "Practical.h"
void DieWithUserMessage(const char *msg, const char *detail) {
fputs(msg, stderr);
fputs(": ", stderr);
fputs(detail, stderr);
fputc('\n', stderr);
exit(1);
}
void DieWithSystemMessage(const char *msg) {
perror(msg);
exit(1);
}
When I do gcc DieWithMessage.c, I get the following error:
/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crt1.o: In function _start':
(.text+0x18): undefined reference tomain'
collect2: ld returned 1 exit status
How do I compile this by itself so that the errors will stop happening when using the makefile?
Thanks for any help.
Your C code needs a main function if you're going to try an link/run it. This is a requirement for hosted C applications under the standard.
That error message indicates what's wrong. The C runtime/startup code (CRT) has an entry point of start which sets up the environment then calls your main. Since you haven't provided a main, it complains.
If you only want to generate an object file for later linking with a main (see here for one description of the process), use something like:
gcc -c -o DieWithMessage.o DieWithMessage.c
(-c is the "compile but don't link" flag). You can then link it later with your main program with something like (although there are other options):
gcc -o myProg myProg.c DieWithMessage.o
If you want a placeholder main to update later with a real one, you can add the following to your code:
int main (void) { return 0; }