I have 4 .c files hello.c,here.c,bye.c and main.c.
One header file mylib.h
The contents are as follows
hello.c
#include<stdio.h>
void hello()
{
printf("Hello!\n");
}
here.c
#include<stdio.h>
void here()
{
printf("I am here \n");
}
bye.c
#include<stdio.h>
void bye()
{
printf("Bye,Bye");
}
main.c
#include<stdio.h>
#include "mylib.h"
int main()
{
hello();
here();
bye();
return 1;
}
mylib.h
#ifndef _mylib_
#define _mylib_
void hello();
void here();
void bye();
#endif
The makefile for creating a static lib is :
Makefile
all: myapp
#Macros
#Which Compiler
CC = gcc
#Where to install
INSTDIR = /usr/local/bin
#Where are include files kept
INCLUDE = .
#Options for developement
CFLAGS = -g -Wall -ansi
#Options for release
#CFLAGS = -O -Wall -ansi
#Local Libraries
MYLIB = mylib.a
myapp: main.o $(MYLIB)
$(CC) -o myapp main.o $(MYLIB)
$(MYLIB): hello.o here.o bye.o
ar rcs $# $^
main.o: main.c mylib.h
hello.o: hello.c
here.o: here.c
bye.o: bye.c
clean:
-rm main.o hello.o here.o bye.o $(MYLIB)
install: myapp
#if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else \
echo "Sorry, $(INSTDIR) does not exist";\
fi
Problem: When I execute the command
make -f Makefile all
I get the error:
gcc -o myapp main.o mylib.a
main.o: In function `main':
/home/usr/molly/main.c:7: undefined reference to `hello()'
/home/usr/molly/main.c:8: undefined reference to `here()'
/home/usr/molly/main.c:9: undefined reference to `bye()'
main.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
make: *** [myapp] Error 1
Questions : How do I resolve this? Why is there an undefined reference
This actually works for me. Try rm mylib.a and then make
This works for me with the caveot that you are not specifying an 'all' target:
xxxx#xxxx-desktop:~/Desktop$ make -f Makefile
cc -g -Wall -ansi -c -o main.o main.c
cc -g -Wall -ansi -c -o hello.o hello.c
cc -g -Wall -ansi -c -o here.o here.c
cc -g -Wall -ansi -c -o bye.o bye.c
ar rcs mylib.a hello.o here.o bye.o
cc -o myapp main.o mylib.a
xxxx#xxxx-desktop:~/Desktop$ ./myapp
Hello!
I am here
Bye,Byexxxx#xxxx-desktop:~/Desktop$
Related
I am struggling with building a program with multiple files whith inter files function calls with makefile in C. Let's say that I have a main file which call a function call_print_hello() declared in a header file fdeclar_macros.h and written in the file script1.c. The function call_print_hello() itself calls another function print_hello() also declared in fdeclar_macros.h and written in script2.c. I have also a makefile but when I run it I get the following error message:
gcc -g -Wall -c main.c
gcc -g -Wall -c script1.c
gcc -o main main.o script1.o
Undefined symbols for architecture x86_64:
"_call_print_hello", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
Here are the content of the files:
makefile:
CC = gcc
CFLAGS = -g -Wall
main: main.o script1.o
$(CC) -o main main.o script1.o
main.o: main.c fdeclar_macros.h
$(CC) $(CFLAGS) -c main.c
script2.o: script2.c fdeclar_macros.h
$(CC) $(CFLAGS) -c script2.c
script1.o: script1.c fdeclar_macros.h
$(CC) $(CFLAGS) -c script1.c
run: main
./main
clean:
$(RM) -rf justify *.dSYM *.o
main.c:
#include "fdeclar_macros.h"
int main(){
call_print_hello();
return 0;
}
fdeclar_macros.h:
#define NUMBER 3
void print_hello();
void call_print_hello();
script1.c:
#include <stdio.h>
#include "fdeclar_macros.h"
void print_hello(){
printf("hello %d\n", NUMBER);
}
script2.c:
#include "fdeclar_macros.h"
void call_print_hello(){
print_hello();
}
The make target for the main executable does not contain a dependency on script2.o and the rule to build main does not link script2.o into the main executable either.
So the linker tries to build an executable with the content of script2.o missing, but as that content is required, linking fails.
One easy fix would be to change the original rule
main: main.o script1.o
$(CC) -o main main.o script1.o
by adding script2.o:
main: main.o script1.o script2.o
$(CC) -o main main.o script1.o script2.o
I will leave finding more general rules as an exercise to the reader.
NAME = my_programm
CC = gcc
CFLAGS = -Wall -Werror -Wextra
MY_SOURCES = main.c script1.c script2.c
MY_OBJECTS = $(MY_SOURCES:.c=.o)
$(NAME): $(MY_OBJECTS)
#cc $(CFLAGS) $(MY_OBJECTS) -o $(NAME)
clean:
#rm -f $(MY_OBJECTS)
#rm -f $(NAME)
run:
./my_programm
I am trying to create a makefile in C but i am facing some issues.
I have my main .c, one .c which keeps the functions implementations and one .h which keeps the functions declarations.
When i try to run the makefile, i get a fatal error.
here is my makefile:
INCL = prog.h
SRC = prog.c prog_fun.c
OBJ = $(SRC:.c=.o)
EXE = prog
CC = gcc
CFLAGS = -c
RM = rm -rf
all: prog
prog: prog.o prog_fun.o
gcc -o prog prog.o prog_fun.o
prog.o: prog.c
gcc -c prog.c
prog_fun.o: prog_fun.c prog.h
gcc -c prog.c
clean:
$(RM) $(OBJ) $(EXE)
The error i get is this:
gcc -c prog.c
prog.c:11:19: fatal error: prog.h: No such file or directory
compilation terminated.
Makefile:17: recipe for target 'prog.o' failed
make: *** [prog.o] Error 1
Can anyone please help me with this?
What you are trying to do by using this
prog_fun.o: prog_fun.c header.h
It should be only
prog_fun.o: prog_fun.c
Modify your make file as
xyz#xyz-PC:~$ vi makefile
INCL = header.h
SRC = prog.c prog_fun.c
OBJ = $(SRC:.c=.o)
EXE = prog
CC = gcc
CFLAGS = -c
RM = rm -rf
all: prog
prog: prog.o prog_fun.o
gcc -o prog prog.o prog_fun.o
prog.o: prog.c
gcc -c prog.c header.h
prog_fun.o: prog_fun.c
gcc -c prog_fun.c header.h
clean:
$(RM) $(OBJ) $(EXE)
next run it
xxyz#xyz-PC:~$ make
gcc -c prog.c header.h
gcc -c prog_fun.c header.h
gcc -o prog prog.o prog_fun.o
I hope it will work now and make sure indention is correct(not manual spaces, it should be tab key)
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
Here is my console output:
Tylers-MacBook-Pro:laser_finder_c tylerjw$ make
gcc -g -Wall -c -o dots_img.o dots_img.c
gcc -g -Wall -c -o no_dots_img.o no_dots_img.c
gcc -g -Wall -c -o point.o point.c
gcc -g -Wall -c -o images.o images.c
gcc -g -Wall -c -o laser_finder_c.o laser_finder_c.c
gcc dots_img.o no_dots_img.o point.o images.o laser_finder_c.o -g -Wall -o laser_finder_c
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [laser_finder_c] Error 1
This doesn't seem to make any sense as the main function is defined in laser_finder_c.c. Below is my makefile. I'm real confused as to why this is happening.
TARGET = laser_finder_c
OBJECTS = dots_img.o no_dots_img.o point.o images.o laser_finder_c.o
#######################################################################################
CFLAGS = -g -Wall
ASFLAGS = -Wall
LDFLAGS = -g -Wall
CC = gcc
AS = gcc
########################################################################################
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $(TARGET)
point.o: point.h
images.o: images.h
laser_finder_c.o: images.h point.h
dots_img.o: images.h
no_dots_img.o: images.h
clean:
rm -f $(OBJECTS) $(TARGET)
Here is the definition of main in laser_finder_c.c
// laser_finder.c - finds the location of laser points comparing two images
#include "point.h"
#include <stdio.h>
#include <stdlib.h>
// #defines ... removed
int main()
{
// ... code removed
return 0;
}
For context the output of gcc -v is:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
This is a sample program i was trying to compile this below c program to know about the
make file.
main.c
#include<stdio.h>
#include "reciprocal.h"
int main(int argc,char **argv){
int i;
i=atoi(argv[1]);
printf("The Reciprocal of %d is %f\n ",i,reciprocal(i));
return 0;
}
reciprocal.c
#include<stdio.h>
#include<assert.h>
#include "reciprocal.h"
double reciprocal(int i){
assert(i!=0);
return 1.0/i;
}
reciprocal.h
#include<stdio.h>
#ifdef __cplusplus
extern "C"{
#endif
extern double reciprocal(int i);
#ifdef __cplusplus
}
#endif
makefile
CFLAGS:=-o2
reciprocal: reciprocal.o main.o
gcc $(CFLAGS) -o reciprocal.o main.o
main.o: main.c reciprocal.h
gcc $(CFLAGS) -c main.c -I ../include
reciprocal.o: reciprocal.c reciprocal.h
gcc $(CFLAGS) -c reciprocal.c -I ../include
clean:
rm -f *.o reciprocal
when compiled as below it throws an error.
% make
gcc -o2 -c reciprocal.c -I ../include gcc -o2 -c main.c -I ../include
gcc -o2 -o reciprocal.o main.o main.o: In function main':
main.c:(.text+0x25): undefined reference toreciprocal' collect2: ld
returned 1 exit status make: * [reciprocal] Error 1
Please help me understand what is the reason for this error.
Change your makefile:
reciprocal: reciprocal.o main.o
gcc $(CFLAGS) -o reciprocal reciprocal.o main.o
^^^^^^^^^^
Alternatively:
reciprocal: reciprocal.o main.o
gcc $(CFLAGS) -o $# $^
You have an insidious typo:
CFLAGS:=-o2
That should have been -O2 with a capital O, this way you redirect the output of every compilation to the file 2.