Compiles in clang but not gcc? - c

I made a library, and I'm trying to make a test client for it to test my Debian packages. This test is being done on Ubuntu 14.04.
I installed the binary and the developer files and their dependencies.
Here's the source for my test program:
#include <stdio.h>
#include <cquel.h>
int main(int argc, char *argv[])
{
cq_init(1024, 128);
struct dbconn mydb = cq_new_connection(u8"pattstest.delwink.com", u8"patts",
u8"patts", u8"pattsdb");
struct dlist *users;
int rc = cq_select_all(mydb, u8"User", &users, u8"");
if (rc)
return 2;
for (size_t i = 0; i < users->fieldc; ++i)
printf("%s\n", users->fieldnames[i]);
cq_free_dlist(users);
return 0;
}
The program is supposed to connect to a test server and get the column headers from the database (no, that server is not production and does not need to be particularly secure).
I attempted to compile using gcc:
$ gcc -Wall `pkg-config --cflags --libs cquel` `mysql_config --cflags --libs` -std=c11 main.c
/tmp/ccjd21kP.o: In function `main':
/home/mac/c/main.c:6: undefined reference to `cq_init'
/home/mac/c/main.c:8: undefined reference to `cq_new_connection'
/home/mac/c/main.c:12: undefined reference to `cq_select_all'
/home/mac/c/main.c:19: undefined reference to `cq_free_dlist'
collect2: error: ld returned 1 exit status
I knew something was up, so I attempted the same with clang:
$ clang -Wall `pkg-config --cflags --libs cquel` `mysql_config --cflags --libs` -std=c11 main.c
Clang compiled just fine! I ran my a.out binary, and it printed the column headers as expected.
Why did gcc fail to link to my library?
EDIT: I thought to check my LD_LIBRARY_PATH to find that it was blank. However, setting it to /usr/lib/x86_64-linux-gnu (which is the location of my shared object) did not change the behavior of gcc.

Order of arguments matter a lot for gcc; you should use
gcc -Wall $(pkg-config --cflags cquel) $(mysql_config --cflags) \
-std=c11 main.c \
$(pkg-config --libs cquel) $(mysql_config --libs)
See also this & that.

Related

undefined main during linking but defined during full compilitaion process

I am novice in C programming. So I learned different process of compilation(preproccessing, compiling, linking). My program is
#include <stdio.h>
#define testDefinition(x) printf(#x " is equal to %lf\n",x)
int main(void)
{
testDefinition(3.15);
return 0;
}
It is simple program which doesn't have any sense,but problem is when I use gcc -o test test.c it works fine, but when I do that
gcc -E test.c -o test.i
gcc -C test.i -o test.o
gcc test.o -o test
I get error
usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
I am using Ubuntu 20.04 and GCC compiler.
test.o is already the executable, you did not pass -c.
$ gcc -E test.c -o test.i
$ gcc -C test.i -o test.o
$ ./test.o
3.15 is equal ....
Because of it, test.o is an ELF file and gcc treats it as shared library (I think). Because there are no source files passed in gcc test.o -o test there is no main, so it's undefined.
I guess, you wanted to do gcc -C -c test.i -o test.o to create an object file.

Unable to compile and link main.c to another source file using gcc

I am trying to compile the following source file using gcc -g -Wall -Wextra -pedantic -std=c99 -o main -lm.
source.h
void simple_sum(void)
source.c
#include "source.h"
#include <stdio.h>
void simple_sum(void)
{
int a, b;
scanf("%d %d", &a, &b);
printf("%d + %d = %d\n",a, b, a + b);
}
main.c
#include "source.h"
#include <stdio.h>
int main(void)
{
printf("\n");
simple_sum();
return 0;
}
I get following error:
gcc -g -Wall -Wextra -pedantic -std=c99 -o main -lm
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function _start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'main' failed
make: *** [main] Error 1
Could someone please suggest how to fix this?
Edit
I get the following error when I run using gcc -g -Wall main.c -o main
/tmp/ccEAL4iG.o: In functionmain':
/home/a/aalto_university/functions/calculation/main.c:7: undefined reference to simple_sum'
collect2: error: ld returned 1 exit status
Compile with
gcc -g -Wall -Wextra -pedantic -std=c99 source.c main.c -o myprog -lm
(actually, -lm is not needed, you don't use <math.h> functions; but keeping -lm should not harm)
Later, learn to write your Makefile to do these things in several steps:
First, get the source.o object file with
gcc -g -Wall -Wextra -pedantic -std=c99 -c source.c
then get the main.o object file with
gcc -g -Wall -Wextra -pedantic -std=c99 -c main.c
At last, link both of them
gcc -g source.o main.o -lm -o myprog
Here
gcc -g -Wall -Wextra -pedantic -std=c99 -o main -lm
you are not providing source file name to linker, hence it throw error like
undefined reference to `main'
While compiling provide source file main.c and source.c. For e.g first run this
gcc -g -Wall -Wextra -pedantic -std=c99 -c main.c source.c -lm
to create the object.o files & then create the executable by running
gcc source.o main.o -o my_exe
And finally run the executable. Also declaration of simple_sum() missing ; it should be
void simple_sum(void); /* you miss ;*/
Also learn how to use Makefile for compilation as #Basile pointed, there you don't have to create .o file manually, your Makefile will create .o file & compile if it's written correctly.

libcheck test fails to link

I'm trying to build a simple example using libcheck but it fails to build while using the flags reported by pkg-config.
My file: tests/test.c
#include <stdlib.h>
#include <check.h>
START_TEST(zero)
{
int z = 0;
ck_assert_int_eq(0, z);
}
END_TEST
Suite* suite_zero(void)
{
Suite* s;
TCase* tc;
s = suite_create("suite_zero");
tc = tcase_create("zero");
tcase_add_test(tc, zero);
suite_add_tcase(s, tc);
return s;
}
int main(void)
{
int number_failed;
SRunner* sr;
Suite* s_zero = suite_zero();
sr = srunner_create(s_zero);
srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
My system:
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"
$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609
$ pkg-config --version
0.29.1
When I try to build my test using the flags and libs reported by pkg-config:
$ pkg-config --cflags --libs check
-pthread -lcheck_pic -pthread -lrt -lm -lsubunit
$ gcc -pthread -lcheck_pic -pthread -lrt -lm -lsubunit -g tests/test.c -o tests/zero
/tmp/ccRV2kLw.o: In function `zero':
Code/tests/test.c:4: undefined reference to `tcase_fn_start'
/Code/tests/test.c:7: undefined reference to `_mark_point'
/Code/tests/test.c:7: undefined reference to `_ck_assert_failed'
/tmp/ccRV2kLw.o: In function `suite_zero':
/Code/tests/test.c:15: undefined reference to `suite_create'
/Code/tests/test.c:16: undefined reference to `tcase_create'
/Code/tests/test.c:17: undefined reference to `_tcase_add_test'
/Code/tests/test.c:19: undefined reference to `suite_add_tcase'
/tmp/ccRV2kLw.o: In function `main':
/Code/tests/test.c:30: undefined reference to `srunner_create'
/Code/tests/test.c:32: undefined reference to `srunner_run_all'
/Code/tests/test.c:33: undefined reference to `srunner_ntests_failed'
/Code/tests/test.c:34: undefined reference to `srunner_free'
collect2: error: ld returned 1 exit status
Libcheck was installed by apt and the library and headers are in the typical locations, /usr/lib and /usr/include respectively. Yet it appears it can't be found. I'm a bit stumped as why. Any ideas?
Thanks.
Try adding the flags reported by pkg-config after the compilation command as this answer and the documentation for pkg-config suggests. The compiler needs to know what file it's trying to link the library to beforehand so that the flags can be applied appropriately.
gcc -g test.c -o test -pthread -lcheck_pic -pthread -lrt -lm -lsubunit
or more succinctly
gcc -g test.c -o test `pkg-config --cflags --libs check`

Undefined references in GSL

I'm trying to link gsl in a small c program.
#include "stdlib.h"
#include "stdio.h"
#include "gsl/gsl_block_float.h"
#include "gsl/gsl_matrix_float.h"
int main(void)
{
gsl_matrix_float* m = gsl_matrix_float_alloc(2, 2);
gsl_matrix_float_fprintf(stdout, m, "%f");
}
I'm compiling with gcc -lgsl -lgslcblas -lm program.c. I've tried gcc $(pkg-config --cflags gsl) $(pkg-config --libs gsl) program.c as well, along with gsl-config. In every case, gcc returns
/tmp/cc1wKgXm.o: In function `main':
program.c:(.text+0x13): undefined reference to `gsl_matrix_float_alloc'
program.c:(.text+0x32): undefined reference to `gsl_matrix_float_fprintf'
collect2: error: ld returned 1 exit status
objdump --syms /usr/lib/libgsl.so | grep gsl_matrix_float returns the proper symbols, as does grepping my headers. Everything is in /usr/lib or /usr/include What am I doing wrong?
I got this from the ubuntu forums. The order of the arguments togcc might be the issue
gcc -o program program.c `gsl-config --cflags --libs`

Issues linking against gstreamer libraries ubuntu 11.10

So I am starting a project that is going to make use of the gstreamer libraries. I am running the test project from the gstreamer documentation and am getting the following error.This program worked properly on archlinux but is erroring out on ubuntu
gcc `pkg-config --cflags --libs gstreamer-0.10` main.c -o player
/tmp/cciFhGCe.o: In function `main':
main.c:(.text+0x1e): undefined reference to `gst_init'
main.c:(.text+0x36): undefined reference to `gst_version'
collect2: ld returned 1 exit status
make: *** [player] Error 1
My code is the following which I got from the gstreamer documentation
#include <stdio.h>
#include <gst/gst.h>
int
main (int argc,
char *argv[])
{
const gchar *nano_str;
guint major, minor, micro, nano;
gst_init (&argc, &argv);
gst_version (&major, &minor, &micro, &nano);
if (nano == 1)
nano_str = "(CVS)";
else if (nano == 2)
nano_str = "(Prerelease)";
else
nano_str = "";
printf ("This program is linked against GStreamer %d.%d.%d %s\n",
major, minor, micro, nano_str);
return 0;
}
and the command I am using to compile is
gcc `pkg-config --cflags --libs gstreamer-0.10` main.c -o player
and the output of pkg-config
-pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gstreamer-0.10 -I/usr/include/libxml2 -pthread -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lxml2 -lgthread-2.0 -lrt -lglib-2.0
So thanks to the great guys on freenode #gstreamer
In unbuntu's version of gcc some changes were made to the ordering of pkg-config statements.
gcc `pkg-config gstreamer-0.10 --cflags` main.c -o player.out `pkg-config gstreamer-0.10 --libs`
Using this format fixed it.

Resources