My makefile is as follows:
BINDIR=/path/to/bin
BK = f1.c f2.c f3.c
BKo= f1.o f2.o f3.o
kl: kl.c $(BK)
#echo "*** Numerical solution ***"
gcc -fopenmp -c kl.c $(BK)
gcc -fopenmp -o $(BINDIR)/kl kl.o $(BKo) -lgsl -lgslcblas -lm
#echo "*** OK ***"
Is -fopenmp included in a correct way in two gcc commands?
Related
After a certain attempt to write a simple program with a main and one function,
I ask for your help to find the bug. I include the 3 files that are in action:
the main function in base.c
the function in fun.c
the makefile
The compiler says that the function is called in a bad way in the main:
undefined reference to `fun'
base.c
#include <stdio.h>
int fun(char c);
main()
{
printf("please enter a single char\n");
char c=getchar();
fun(c);
return 0;
}
fun.c
#include <stdio.h>
int fun(char c)
{
printf("%d3 is the value of your char!\n", 'c');
return 0;
}
makefile
charprint: base.o fun.o
gcc -g -Wall -ansi base.o fun.o -o charprint
base.o: base.c
gcc -g -Wall -ansi base.c -o base.o
fun.o: fun.c
gcc -g -Wall -ansi fun.c -o fun.o
The compilation problem is that you forgot the -c flags in the compiler line for base.o and fun.o. One obvious simple (but not very good) way to fix that is:
charprint: base.o fun.o
gcc -g -Wall -ansi base.o fun.o -o charprint
base.o: base.c
gcc -c -g -Wall -ansi base.c -o base.o
fun.o: fun.c
gcc -c -g -Wall -ansi fun.c -o fun.o
Interestingly, the simplest fix would be to delete the two compiler command for the two object files — make knows how to compile C files to object files. You could set CFLAGS += -Wall (or CFLAGS = -Wall) to get the (very important) -Wall flag included. Adding -Werror too would be good.
CFLAGS += -Wall -Werror -g -std=c11
charprint: base.o fun.o
${CC} ${CFLAGS} base.o fun.o -o $#
base.o: base.c
fun.o: fun.c
In the code for fun(), your argument to printf() should be just c and not 'c'. You probably also mean %3d rather than %d3 though that 'works'; it just doesn't do what you expect. Note that you should use an explicit int main(void) { … }. And you should probably create a header fun.h containing:
extern int fun(char c);
and #include "fun.h" in both source files, and add fun.h after the source file name in the dependency lines in the makefile:
CFLAGS += -Wall -Werror -g -std=c11
charprint: base.o fun.o
${CC} ${CFLAGS} base.o fun.o -o $#
base.o: base.c fun.h
fun.o: fun.c fun.h
In fact, you don't need to list the source files as dependencies for the object files; make will infer that dependency automatically. But you do need to specify the header file dependency.
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.
I want to be able to use a variable in my code that is the git version. If I set the variable with make and then override it in a .h file then the final value that prints wil lbe from the '.h' file. Is there a way to override the .h from the makefile?
executing make
gcc -O2 -pipe -pedantic -std=c99 -Wall -O3 -ledit -DVERSION=\"\" -c main.c -o main.o
In file included from main.c:9:0:
openshell.h:17:0: warning: "VERSION" redefined [enabled by default]
#define VERSION "v0.1a"
I'm trying to set my variable VERSION from github so that a version can be viewed:
$ ./a.out --version
OpenShell version 0.1(a)
Version: v0.1a-2-gc6b1-dirty
I have this makefile
CC = gcc
GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags)
CFLAGS := $(CFLAGS) -pedantic -std=c99 -Wall -O3 -ledit -g -DVERSION=\"$(GIT_VERSION)\"
shell: main.o
$(CC) -o shell main.o errors.c util.c pipeline.c -ledit
main.o: main.c errors.c util.c
.PHONY: clean
clean:
rm -f *.o
Then it works on Linux Ubuntu but it doesn't work on BSD, with PC-BSD the variable is not shown:
dac:/usr/home/dac/openshell $ make
The Command is: make
27152: executing make
gcc -O2 -pipe -pedantic -std=c99 -Wall -O3 -ledit -DVERSION=\"\" -c main.c -o main.o
main.c: In function 'trimstring':
main.c:116:9: warning: value computed is not used [-Wunused-value]
*tmp++;
^
main.c:119:17: warning: comparison between pointer and integer [enabled by default]
while (*tmp != NULL) {
^
main.c: In function 'exec_program':
main.c:444:9: warning: implicit declaration of function 'snprintf' [-Wimplicit-function-declaration]
snprintf(shell_prompt, sizeof(shell_prompt), "%s:%s $ ", getenv("USER"), getcwd(NULL, 1024));
^
main.c:444:9: warning: incompatible implicit declaration of built-in function 'snprintf' [enabled by default]
gcc -o shell main.o errors.c util.c pipeline.c -ledit
dac:/usr/home/dac/openshell $ ./shell --version
The Command is: ./shell --version
27181: executing ./shell
OpenShell version 0.1(a)
Version:
dac:/usr/home/dac/openshell $
Update 160426 07:49 CET
Now it works with Ubuntu (but maybe dangerous deleting the old version number in the .h file) `GIT:= $(shell head -n -1 openshell.h > temp.txt ; mv temp.txt openshell.h;git describe --abbrev=4 --dirty --always --tags > VERSION; echo "#define VERSION \"$(GIT_VERSION)\"" >> openshell.h)
The updated Makefile is now:
CC = gcc
GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags)
CFLAGS := $(CFLAGS) -L/usr/local/include/ -L/usr/include -pedantic -std=c99 -Wall -O3 -g -DVERSION=\"$(GIT_VERSION)\" -ledit -lncurses
LDIRS = -L/usr/local/lib -L/usr/lib
LIBS = -ledit lncurses -lcurses
shell: main.o
$(CC) -o shell main.o errors.c util.c pipeline.c -ledit -lncurses -lcurses
main.o: main.c errors.c util.c
USERNAME := $(shell whoami >> username.txt)
GIT:= $(shell head -n -1 openshell.h > temp.txt ; mv temp.txt openshell.h;git describe --abbrev=4 --dirty --always --tags > VERSION; echo "\#define VERSION \"$(GIT_VERSION)\"" >> openshell.h)
.PHONY: clean
clean:
rm -f *.o
`
To avoid warning: "VERSION" redefined, wrap the #define with #ifndef:
#ifndef VERSION
#define VERSION "v0.1a"
#endif
Hello to the good people of Stack Overflow, I am back at it again with the questions! haha
So I have a couple of files that I am trying to compile and link together. The library I have created is a DLL. Using a RTLD_LAZY method. I have the library in the same directory as the application. I'm having a tough time completing this task. I'm trying to link it using -ldl.
My files that I have are:
lab3.c //Which has my main
myLibrary.c //which is my library
sdv.h //which is my header file
testDynamic.c //which is my handle file for the RTLD_LAZY
Here is what I have done so far, but I'm clearly screwing something up..
dynamic: lab3.o myLibrary.o test
gcc -o dynamic lab3.o myLibrary.o -lm
lab3.o: lab3.c
gcc -fPIC -c -o lab3.o lab3.c -lm
myLibrary.o: myLibrary.c
gcc -fPIC -c myLibrary.c -o myLibrary.o -lm
libmyLibrary.so: myLibrary.o
gcc -shared -o libmyLibrary.so myLibrary.o -lm
testDynamic.o:
gcc testDynamic.c -L. -lmyLibrary -o test -ldl
export LD_LIBRARY_PATH=./
Any advice will be greatly appreciated! Thanks in advance!
Here comes an example close to your own makefile.
makefile:
CC=gcc
CFLAGS=-Wall -Wextra -Werror -std=gnu99
.PHONY:all mrproper clean
all:libmyLibrary.so dynamic testDynamic
dynamic:lab3.o
$(CC) $(CFLAGS) -o dynamic lab3.o -L. -lmyLibrary -lm
lab3.o:lab3.c
$(CC) $(CFLAGS) -c -o lab3.o lab3.c
myLibrary.o:myLibrary.c
$(CC) $(CFLAGS) -fPIC -c myLibrary.c -o myLibrary.o
libmyLibrary.so:myLibrary.o
$(CC) $(CFLAGS) -shared -o libmyLibrary.so myLibrary.o -lm
testDynamic.o:testDynamic.c
$(CC) $(CFLAGS) -o testDynamic.o -c testDynamic.c
testDynamic:testDynamic.o
$(CC) $(CFLAGS) -o testDynamic testDynamic.o -ldl
mrproper:clean
rm -f dynamic libmyLibrary.so testDynamic
clean:
rm -f lab3.o myLibrary.o testDynamic.o
Use -lm only when linking. -fPic is only necessary when linking dynamic library. -lmyLibrary is only necessary when linking program with dynamic library. So generating testDynamic does not need it as it will load library dynamically, it does not require being linked to it.
sdv.h:
#ifndef SDV_H
#define SDV_H
extern void sdv_print_version();
#endif
myLibrary.c:
#include <stdio.h>
#include <stdlib.h>
void sdv_print_version()
{
printf("v1.0\n");
}
testDynamic.c:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#define MY_LIB "libmyLibrary.so"
#define PRINT_VERSION "sdv_print_version"
int main()
{
void *handle = dlopen(MY_LIB, RTLD_LAZY);
if (handle == NULL)
{
fprintf(stderr, "%s\n", dlerror());
return 1;
}
void (*p_print_version)() = NULL;
p_print_version = dlsym(handle, PRINT_VERSION);
if (p_print_version == NULL)
{
printf("No version available.\n");
fprintf(stderr, "%s\n", dlerror());
}
else
{
(*p_print_version)();
}
if (dlclose(handle) != 0)
{
fprintf(stderr, "%s\n", dlerror());
}
return 0;
}
Now building:
>make
gcc -Wall -Wextra -Werror -std=gnu99 -fPIC -c myLibrary.c -o myLibrary.o
gcc -Wall -Wextra -Werror -std=gnu99 -shared -o libmyLibrary.so myLibrary.o -lm
gcc -Wall -Wextra -Werror -std=gnu99 -c -o lab3.o lab3.c
gcc -Wall -Wextra -Werror -std=gnu99 -o dynamic lab3.o -L. -lmyLibrary -lm
gcc -Wall -Wextra -Werror -std=gnu99 -o testDynamic.o -c testDynamic.c
gcc -Wall -Wextra -Werror -std=gnu99 -o testDynamic testDynamic.o -ldl
Let's keep a first version of dynamic library:
>mkdir v1.0
>mv libmylibrary.so v1.0/
Now update myLibrary.c:
#include <stdio.h>
#include <stdlib.h>
void sdv_print_version()
{
printf("v2.0\n");
}
Build again:
>make
gcc -Wall -Wextra -Werror -std=gnu99 -fPIC -c myLibrary.c -o myLibrary.o
gcc -Wall -Wextra -Werror -std=gnu99 -shared -o libmyLibrary.so myLibrary.o -lm
Let's move this new dynamic library to another directory:
>mkdir v2.0
>mv libmylibrary.so v2.0/
Now testing with no dynamic library available:
>export LD_LIBRARY_PATH=./
>PATH=$PATH:.
>dynamic
dynamic: error while loading shared libraries: libmyLibrary.so: cannot open shared object file: No such file or directory
>testDynamic
libmyLibrary.so: cannot open shared object file: No such file or directory
What's the difference? In "testDynamic.c" we could, instead of showing a message error, do an alternative algorithm not requiring "libmyLibrary.so".
Now checking we can use "libmyLibrary.so":
>cd v1.0
>../dynamic
v1.0
>../testDynamic
v1.0
>cd ../v2.0
>../dynamic
v2.0
>../testDynamic
v2.0
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Repeated Multiple Definition Errors from including same header in multiple cpps
I'm hitting the following error when compiling a third-party src:
.libs/lib_udf_la-udf.o:(.rodata+0x240): multiple definition of `SHIFT_TABLE'
.libs/lib_udf_la-hll.o:(.rodata+0x0): first defined here
The project is set up with autotools; my Makefile.ag references the following:
SOURCES = hll.c udf.c udf.h
hll.c references hll.h
udf.c references hll.h
hll.h has some const like this:
hll.h has the #ifndef HLL_H ... #endif thing to avoid double defs
int const SHIFT_TABLE[1024] = {...}
I don't understand why I'm hitting multiple definitions, I'm guessing it has to do with the link step, but it is a long time since I dabbled with C.
Here's the cc/link output for reference:
make[1]: Entering directory `/home/mping/workspace/monetdb/MonetDB-11.13.5/sql/backends/monet5/UDF'
/bin/bash ../../../../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I../../../.. -I. -I.. -I./.. -I../../../include -I./../../../include -I../../../common -I./../../../common -I../../../storage -I./../../../storage -I../../../server -I./../../../server -I../../../../monetdb5/modules/atoms -I./../../../../monetdb5/modules/atoms -I../../../../monetdb5/modules/kernel -I./../../../../monetdb5/modules/kernel -I../../../../monetdb5/mal -I./../../../../monetdb5/mal -I../../../../monetdb5/modules/mal -I./../../../../monetdb5/modules/mal -I../../../../monetdb5/optimizer -I./../../../../monetdb5/optimizer -I../../../../clients/mapilib -I./../../../../clients/mapilib -I../../../../common/options -I./../../../../common/options -I../../../../common/stream -I./../../../../common/stream -I../../../../gdk -I./../../../../gdk -DLIBUDF -g -O2 -c -o lib_udf_la-hll.lo `test -f 'hll.c' || echo './'`hll.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I../../../.. -I. -I.. -I./.. -I../../../include -I./../../../include -I../../../common -I./../../../common -I../../../storage -I./../../../storage -I../../../server -I./../../../server -I../../../../monetdb5/modules/atoms -I./../../../../monetdb5/modules/atoms -I../../../../monetdb5/modules/kernel -I./../../../../monetdb5/modules/kernel -I../../../../monetdb5/mal -I./../../../../monetdb5/mal -I../../../../monetdb5/modules/mal -I./../../../../monetdb5/modules/mal -I../../../../monetdb5/optimizer -I./../../../../monetdb5/optimizer -I../../../../clients/mapilib -I./../../../../clients/mapilib -I../../../../common/options -I./../../../../common/options -I../../../../common/stream -I./../../../../common/stream -I../../../../gdk -I./../../../../gdk -DLIBUDF -g -O2 -c hll.c -fPIC -DPIC -o .libs/lib_udf_la-hll.o
/bin/bash ../../../../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I../../../.. -I. -I.. -I./.. -I../../../include -I./../../../include -I../../../common -I./../../../common -I../../../storage -I./../../../storage -I../../../server -I./../../../server -I../../../../monetdb5/modules/atoms -I./../../../../monetdb5/modules/atoms -I../../../../monetdb5/modules/kernel -I./../../../../monetdb5/modules/kernel -I../../../../monetdb5/mal -I./../../../../monetdb5/mal -I../../../../monetdb5/modules/mal -I./../../../../monetdb5/modules/mal -I../../../../monetdb5/optimizer -I./../../../../monetdb5/optimizer -I../../../../clients/mapilib -I./../../../../clients/mapilib -I../../../../common/options -I./../../../../common/options -I../../../../common/stream -I./../../../../common/stream -I../../../../gdk -I./../../../../gdk -DLIBUDF -g -O2 -c -o lib_udf_la-udf.lo `test -f 'udf.c' || echo './'`udf.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I../../../.. -I. -I.. -I./.. -I../../../include -I./../../../include -I../../../common -I./../../../common -I../../../storage -I./../../../storage -I../../../server -I./../../../server -I../../../../monetdb5/modules/atoms -I./../../../../monetdb5/modules/atoms -I../../../../monetdb5/modules/kernel -I./../../../../monetdb5/modules/kernel -I../../../../monetdb5/mal -I./../../../../monetdb5/mal -I../../../../monetdb5/modules/mal -I./../../../../monetdb5/modules/mal -I../../../../monetdb5/optimizer -I./../../../../monetdb5/optimizer -I../../../../clients/mapilib -I./../../../../clients/mapilib -I../../../../common/options -I./../../../../common/options -I../../../../common/stream -I./../../../../common/stream -I../../../../gdk -I./../../../../gdk -DLIBUDF -g -O2 -c udf.c -fPIC -DPIC -o .libs/lib_udf_la-udf.o
/bin/bash ../../../../libtool --tag=CC --mode=link gcc -DLIBUDF -g -O2 -module -avoid-version -o lib_udf.la -rpath /usr/local/lib/monetdb5 lib_udf_la-hll.lo lib_udf_la-udf.lo ../../../../monetdb5/tools/libmonetdb5.la ../../../../gdk/libbat.la
libtool: link: gcc -shared -fPIC -DPIC .libs/lib_udf_la-hll.o .libs/lib_udf_la-udf.o -Wl,-rpath -Wl,/home/mping/workspace/monetdb/MonetDB-11.13.5/monetdb5/tools/.libs -Wl,-rpath -Wl,/home/mping/workspace/monetdb/MonetDB-11.13.5/gdk/.libs ../../../../monetdb5/tools/.libs/libmonetdb5.so ../../../../gdk/.libs/libbat.so -O2 -pthread -Wl,-soname -Wl,lib_udf.so -o .libs/lib_udf.so
When you define array int const SHIFT_TABLE[1024] = {...} in the header file. and then you make reference to the header file in 2 c file in the same project It's like of defining the array twice in the 2 c files. and that's the cause of your problem.
Even If you use #ifndef that's will not avoid your preprocess to include the definition in the second C file
From Preprocessor #ifndef:
Standard headers may be included in any order; each may be included
more than once in a given scope, with no effect different from being
included only once
You can check that in the preprocess code you will find that the array is defined twice and that's wrong. you can generate your preprocess code with gcc -E
the #ifndef works only when you check the constant macro in different header files and not in the same header file
To avoid that problem you can define your array in one of the c file. And you define the array as extern in the header file
In one of the C files:
int const SHIFT_TABLE[1024] = {...};
In the header file:
extern int const SHIFT_TABLE[1024];