I am on Debian 10 and I want to develop an C application for PostgreSQL. This is why I installed a packages postgresql and libpq-dev. Later clearly installed header files inside the system folders:
┌───┐
│ $ │ ziga > ziga--workstation > 001--hello_world
└─┬─┘
└─> find /usr/include/ | grep libpq
/usr/include/postgresql/libpq-fe.h
/usr/include/postgresql/libpq
/usr/include/postgresql/libpq/libpq-fs.h
/usr/include/postgresql/libpq-events.h
/usr/include/postgresql/internal/libpq
/usr/include/postgresql/internal/libpq/pqcomm.h
/usr/include/postgresql/internal/libpq-int.h
But when I compile this simple C program:
#include <stdio.h>
#include <postgresql/libpq-fe.h>
int main(int argc, char * argv[]){
int v = PQlibVersion();
printf("Version of libpq: %d\n", v);
return 0;
}
compiler says:
gcc -std=c17 -Wall -Wpedantic -g -gdwarf-2 -o main.elf main.c
/usr/bin/ld: /tmp/ccVzig6T.o: in function `main':
/home/ziga/Dropbox/workspace/racunalnistvo/projects--pistam/2021-03-03--postgressql_c/001--hello_world/main.c:6: undefined reference to `PQlibVersion'
collect2: error: ld returned 1 exit status
make: *** [makefile:59: main.elf] Error 1
I don't understand. Header files are inside /usr/include where they should be found...
Is library not being found or what? It is also installed...
┌───┐
│ $ │ ziga > ziga--workstation > 001--hello_world
└─┬─┘
└─> find /usr/lib | grep libpq
/usr/lib/x86_64-linux-gnu/libpq.a
/usr/lib/x86_64-linux-gnu/libpq.so
/usr/lib/x86_64-linux-gnu/libpq.so.5
/usr/lib/x86_64-linux-gnu/pkgconfig/libpq.pc
/usr/lib/x86_64-linux-gnu/libpq.so.5.11
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/pqsignal.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/be-secure-openssl.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/auth.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/pqcomm.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/be-fsstubs.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/pqformat.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/ifaddr.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/be-secure.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/pqmq.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/crypt.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/be-secure-common.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/hba.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/auth-scram.bc
/usr/lib/postgresql/11/lib/libpqwalreceiver.so
Can anyone tell me how to best solve this?
As the log says, The linker is unable to find any reference to PQlibVersion. Since the linker is running, it clearly is not a problem of compiling but linking.
/usr/bin/ld: /tmp/ccVzig6T.o: in function `main':
/home/ziga/Dropbox/workspace/racunalnistvo/projects--pistam/2021-03-03--postgressql_c/001--hello_world/main.c:6: undefined reference to `PQlibVersion'
collect2: error: ld returned 1 exit status
I think you should add linker options to link against the postgress library. Add -lpq option to you compiler arguments. For a more complete explanation, please read Building libpq Programs.
Related
I'm trying to write my own shared library to link to an executable, but can't get the .so to link.
I'm using a very basic example to try and get it working. The shared library (test_lib.c):
#include "test_lib.h" //stdlib includes and function prototype
char *hello(void) {
char *c = malloc(100);
memcpy(c, "hello\n", 7);
return c;
}
The executable (test.c):
#include "test_lib.h"
int main() {
printf("%s", hello());
return 0;
}
Following all the guides I can find, I compile the .so with gcc -I . -fPIC -shared -o test_lib.so test_lib.c, and then the executable (in the same directory) with gcc -I . -L . test.c -ltest_lib
This gives the error:
/usr/bin/ld: cannot find -ltest_lib
collect2: error: ld returned 1 exit status
As I understand including the path through the -L flag should tell gcc where to find the .so, but this isn't working. What am I missing here?
When linking a library, the library usually has to be named libxxx.a|so for the linker to find it.
Compiling the library:
gcc -I . -fPIC -shared -o libtest.so test_lib.c
Then you can link with:
gcc -I . -L . test.c -ltest
I am trying to use a 3rd party library (.so) file in my project. A very simple program to do that:
#include "LibGent.h"
#include "genttypes.h"
int main() {
GT_LIB* gtLib = LibGentGet();
return 0;
}
I compile/link the program above against libgent.so:
gcc testing.c -L/home/username/proj -lgent
I get the following error:
/tmp/ccALOJwU.o: In function `main': testing.c:(.text+0x11): undefined reference to `LibGentGet'
collect2: error: ld returned 1 exit status
However, I can see that the function LibGentGet is defined in the .so file:
readelf -Ws libgent.so | grep "LibGentGet"
301: 0000000000044820 8 FUNC LOCAL DEFAULT 8 LibGentGet
What am I doing wrong?
I get linker error while compiling a minimal program that uses getaddrinfo_a on Linux. The program in question
#define _GNU_SOURCE
#include <stdio.h>
#include <netdb.h>
int main(int argc, char **argv) {
int err;
err = getaddrinfo_a(0, NULL, 0, NULL);
}
Compiler output:
$ cc -lanl minimal.c
/tmp/cc89BuFU.o: In function `main':
minimal.c:(.text+0x24): undefined reference to `getaddrinfo_a'
collect2: error: ld returned 1 exit status
$ cc --version
cc (Ubuntu 4.9.2-10ubuntu13) 4.9.2
You are using command in wrong way. Use
cc minimal.c -lanl
-lanl should come after not before file name.
gcc [options] [source files] [object files] [-Ldir] -llibname [-o outfile]
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
-l 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.
According to standard also, order of library matters. Linker didn't check for symbol from previously specified libraries. Ref
The library to link must be put after the object (and source files in your case):
$ cc minimal.c -lanl
I am having slight problems with using makefile in C. Ive been following a tutorial in a textbook, but it doesnt seem to want to work. I have three files, message_hider.c, encrypt.h and encrypt.c. When I create a makefile for these files it returns an error, but when I run each command individually it works just fine. Here are my files.
encrypt.c
#include "encrypt.h"
void encrypt(char *message) {
char c;
while (*message) {
*message = *message ^ 31;
message++;
}
}
message_hider.c
#include <stdio.h>
#include "encrypt.h"
int main() {
char msg[80];
while (fgets(msg, 80, stdin)) {
encrypt(msg);
printf("%s", msg);
}
}
encrypt.h
void encrypt(char *message);
Makefile
message_hider: message_hider.o encrypt.o
gcc message_hider.o encrypt.o -o message_hider
message_hider.o: message_hider.c encrypt.h
gcc -c message_hider.c
encrypt.o: encrypt.c encrypt.h
gcc -c encrypt.c
Error message
$ make message_hider
cc message_hider.o -o message_hider
message_hider.o:message_hider.c:(.text+0x17): undefined reference to `encrypt'
message_hider.o:message_hider.c:(.text+0x17): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `encrypt'
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../x86_64-pc-cygwin/bin/ld: message_hider.o: bad reloc address 0x0 in section `.pdata'
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../x86_64-pc-cygwin/bin/ld: final link failed: Invalid operation
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'message_hider' failed
make: *** [message_hider] Error 1
$ make message_hider
cc message_hider.o -o message_hider
That is not the rule you've specified in your makefile. First off, it appears to be using cc rather than gcc. Second, there's no mention of encrypt.o in there which is why your link is failing.
Try to explicitly use the makefile, such as with:
make -f Makefile message_hider
It may be that it's picking up a different makefile, one that either has different rules or one that simply relies on the default rules like .c.o.
And, based on your update that:
make -f Makefile message_hider
gives you:
$ make -f Makefile message_hider
make: Makefile: No such file or directory
make: *** No rule to make target 'Makefile'. Stop.
that's the error you get when Makefile does not actually exist.
So you need to check that it's in the current directory, and named exactly as you expect.
That would explain the use of default rules as mentioned earlier, since your makefile isn't actually being picked up.
Another thing to check, though it's probably moot now that we've seen the error above, is that you're actually running the correct make program. Use which make to find out where it is (should be /usr/bin/make on CygWin) and make --version to check the version.
I am using Cygwin environment with Lua Interpreter package included while cygwin installation.
So I am able to compile and run sample lua progs.
But when i try to execute a sample c file which has lua calls , i am always getting this following error.
$ cc -o ../samples/ctest -Wall ../samples/ctest.c
/tmp/ccOYgLj4.o:ctest.c:(.text+0x2b): undefined reference to `_luaL_newstate'
/tmp/ccOYgLj4.o:ctest.c:(.text+0x3d): undefined reference to `_luaL_openlibs'
/tmp/ccOYgLj4.o:ctest.c:(.text+0x59): undefined reference to `_luaL_loadfile'
/tmp/ccOYgLj4.o:ctest.c:(.text+0x82): undefined reference to `_lua_pcall'
/tmp/ccOYgLj4.o:ctest.c:(.text+0xb8): undefined reference to `_lua_getfield'
/tmp/ccOYgLj4.o:ctest.c:(.text+0xd5): undefined reference to `_lua_call'
/tmp/ccOYgLj4.o:ctest.c:(.text+0xf0): undefined reference to `_lua_close'
collect2: ld returned 1 exit status
My sample ctest.c file contents:
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
/* lua interpreter */
lua_State* l;
int main () {
int dofile;
/* initialize lua */
l = lua_open();
/* load lua libraries */
luaL_openlibs(l);
/* run the hello.lua script */
dofile = luaL_dofile(l, "hello.lua");
if (dofile == 0) {
/* call foo */
lua_getglobal(l,"foo");
lua_call(l,0,0);
}
else {
printf("Error, unable to run hello.lua\n");
}
/* cleanup Lua */
lua_close(l);
return 0;
}
hello.lua file contents:
print("from c hurray")
on searching the net everywhere they say some linker error and have to include -llua51. So i tried the following .
$ cc -o ../samples/ctest -Wall -llua5.1 ../samples/ctest.c
/tmp/cc3v5Nim.o:ctest.c:(.text+0x2b): undefined reference to `_luaL_newstate'
/tmp/cc3v5Nim.o:ctest.c:(.text+0x3d): undefined reference to `_luaL_openlibs'
/tmp/cc3v5Nim.o:ctest.c:(.text+0x59): undefined reference to `_luaL_loadfile'
/tmp/cc3v5Nim.o:ctest.c:(.text+0x82): undefined reference to `_lua_pcall'
/tmp/cc3v5Nim.o:ctest.c:(.text+0xb8): undefined reference to `_lua_getfield'
/tmp/cc3v5Nim.o:ctest.c:(.text+0xd5): undefined reference to `_lua_call'
/tmp/cc3v5Nim.o:ctest.c:(.text+0xf0): undefined reference to `_lua_close'
collect2: ld returned 1 exit status
Vedhashree#Vedhashree-PC /cygdrive/c/cygwin/bin
$ ls /usr/lib/liblua*.a
/usr/lib/liblua.a /usr/lib/liblua5.1.a
/usr/lib/liblua.dll.a /usr/lib/liblua5.1.dll.a
Can you help me fix this issue and make my first embedded lua c program work?
Update:
$ cc -o ctesing -Wall ctesting.c -llua5.1
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld: cannot find
-llua5.1
collect2: ld returned 1 exit status
-----------------------------------------------------------------
cc -o ../samples/ctest -Wall ../samples/ctest.c -llua
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld: cannot find
-llua51
collect2: ld returned 1 exit status
-----------------------------------------------------------------
cc -o ../samples/ctest -Wall ../samples/ctest.c -llua51
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld: cannot find
-llua
collect2: ld returned 1 exit status
-----------------------------------------------------------------
Still I get only these errors :(
Place -llua5.1 after ../samples/ctest.c. Objects should be linked in reverse order of dependency.
cc -o ../samples/ctest -Wall ../samples/ctest.c -llua5.1
UPDATE: Your update describes a different problem. In this case the linker cannot find a liblua5.1.a file in its search path. Make sure that you have such a library on your system and try adding its path using the -L option.