I'm trying to compile a project that has multiple *.c files and *.h file when I type the following command:
$gcc -c -I ../hdr main.c gestic.c menu.c
the hdr folder is where the *.h files are located, the .o files are created but when I try to link them using the command:
$gcc -o main.o gestic.o menu.o
I see errors
gestic.c:(.text+0x..): undefined reference to functions that are declared in *.h files
$gcc -Wall -c -I../hdr -o main.o main.c
$gcc -Wall -c -I../hdr -o menu.o menu.c
$gcc -Wall -c -I../hdr -o gestic.o gestic.c
$gcc -Wall -o myprogram main.o menu.o gestic.o
Using a Makefile is very common for this task
example (untested) Makefile:
CC=gcc
CFLAGS=-Wall -I../hdr
all: myprogram
myprogram: main.o menu.o gestic.o
$(CC) -o $# $^
gestic.o: gestic.c
$(CC) $(CFLAGS) -c -o $# $<
main.o: main.c
$(CC) $(CFLAGS) -c -o $# $<
menu.o: menu.c
$(CC) $(CFLAGS) -c -o $# $<
Try:
$ gcc main.o gestic.o menu.o
-o filename: Place output in filename
Firstly header files are not included, secondly you might use the function that doesn't contain the definition.
The message undefined reference to 'function_name' implies that of all the object files you're giving to the linker, none of them has a definition for function_name. That means that either
You're not linking with *.o
*.c (as compiled) does not contain a definition for function_name -- by 'as compiled' I mean with all of the various preprocessor options you use on it.
here -Iinclude/
try,
gcc -c file.c -I<include_dir>
If you compile more files better to have makefile to create the objects of those files, link those objects along with header.
Sample makefile,
CC = gcc
CFLAGS = -Wall
INCLUDE = sample.h
OBJ = samople1.o sample2.o
%.o: %.c $(INCLUDE)
$(CC) $(CFLAGS) -c -o $# $<
go: $(OBJ)
gcc $(CFLAGS) -o $# $^
Related
I would like to specify a repository for an object I generate in my makefile.
I searched for a while but only found elaborate solutions, for a list of objects, while I would like to TARGET ONE OBJECT ONLY.
(makefile is new for me, so the simpler the better)
Here is my code:
///////////////////////////////////
*definition of several directories*
*definition of CC, CFLAGS, CInclude*
cutgen:
$(CC) $(CFlags) -D__LINUX__ $(CDir)cutgen.c -o cutgen
check: cutgen cutcheck.c *list of objects here*
$(CC) $(CFlags) -I $(CHeaderDir) cutcheck.c *list of objects here* -o cutcheck
./cutcheck
cutcheck.c: cutgen test.o
./cutgen $(CDir)test.c -o cutcheck.c
test.o: util.o
$(CC) $(CFlags) -c $(CInclude) $(CDir)test.c
util.o: config.o
$(CC) $(CFlags) -c $(CInclude) $(GenDir)util.c
...
...
stubs.o:
$(CC) $(CFlags) $(CInclude) -c $(StubsDir)stubs.c
clean:
rm -f *.o *~ cutcheck* cutgen
all: check
///////////////////////////////////
Here for example, I would like to generate util.o in the Objects folder.
Any help would be appreciated, thank you in advance !
$(Objects)/util.o: config.o
$(CC) $(CFlags) -c $(CInclude) $(GenDir)util.c -o $#
(And are you sure about that prerequisite? I think $(GenDir)util.c might be better than config.o.)
FC= ifort
FCFLAGS=-O2 -r8 -openmp -mcmodel=large -extend-source -shared-intel -I$(HOME)/usr/include
LDFLAGS=-L$(HOME)/usr/lib -lfftw3 -lm
TARGET=Project
Project: a.o b.o c.o d.o
#
all : $(TARGET)
%: %.o
$(FC) $(FCFLAGS) -o $# $^ $(LDFLAGS)
%.o: %.f90
$(FC) $(FCFLAGS) -c $<
all : $(TARGET)
clean :
rm *.o
when I studied makefile, there is no information for
#
all : $(TARGET)
and function of % and $^. I wanna check about these things. Thanks for your help.
all is a target (repeated twice in that makefile for no reason). So is clean. Targets are how make works. See Rule Example.
$^ is one of the Automatic Variables available for use in target recipes.
% is a wildcard used in some make functions and in Pattern Rules.
I was doing makefile test for creating static library and creating dynamic library from it. I have foo.h foo.c bar.c and main.c files in my directory.
I wrote a Makefile as follows:
#This makefile demonstrate the shared and static library creation.
CFLAGS = -Wall -Werror -fPIC
CFLAGS1 = -Wall
inc = /home/betatest/Public/implicit-rule-archive
all : foo.o bar.o libfoo.a libfoo.so run
foo.o: foo.c foo.h
#echo "Making the foo.o"
$(CC) -c $(CFLAGS) $< -o $#
bar.o : bar.c foo.h
#echo "Making the bar.o"
$(CC) -c $(CFLAGS) $< -o $#
libfoo.a(foo.o bar.o) : foo.o bar.o
ar cr $# $^
libfoo.so : libfoo.a
$(CC) -shared -o $# $^
run : main.c
$(CC) -L$(inc) $(CFLAGS1) -o $# $< -lfoo
.PHONY : clean
clean :
-rm -f *.o run libfoo.*
while making it gives the following the following errors:
Making the foo.o
cc -c -Wall -Werror -fPIC foo.c -o foo.o
Making the bar.o
cc -c -Wall -Werror -fPIC bar.c -o bar.o
make: *** No rule to make target 'libfoo.a', needed by 'all'. Stop.
I have written the archive statement as :
libfoo.a(foo.o bar.o) : foo.o bar.o
ar cr $# $^
from this to:
libfoo.a(*.o) : *.o
ar cr $# $^
Can I write the statement like this because in both the cases the error is the same.
I don't understand where I am going wrong. Thanks!!!!!
Instead of libfoo.a(foo.o bar.o) you want plain libfoo.a : foo.o bar.o.
Another thing is that .a files are normally built for linking against the final executable, hence object files for .a are compiled as position-dependent code. Shared libraries, on the other hand, require code compiled as position independent.
Hence, you can:
Get rid of libfoo.a.
Produce header dependencies automatically.
Establish complete dependencies on your targets so that make -j works robustly.
Set rpath so that run always finds libfoo.so in its directory.
This way:
CFLAGS = -Wall -Werror
LDFLAGS = -L/home/betatest/Public/implicit-rule-archive -Wl,-rpath,'$$ORIGIN'
all : run
run : main.o libfoo.so
$(CC) $(LDFLAGS) -o $# $^
libfoo.so : CFLAGS += -fPIC # Build objects for .so with -fPIC.
libfoo.so : foo.o bar.o
$(CC) -shared -o $# $^
# Compile any .o from .c. Also make dependencies automatically.
%.o : %.c
$(CC) -c $(CFLAGS) -o $# -MD -MP $<
# Include dependencies on subsequent builds.
-include $(wildcard *.d)
.PHONY : all clean
clean :
-rm -f *.o *.d run libfoo.*
I am trying to write a makefile for a small project which uses GTK libraries.
# Compiler
cc = gcc
#Options for Development
CFLAGS = `pkg-config --cflags --libs gtk+-2.0`
all: pss
pss : main.o interface.o
# $(cc) $(CFLAGS) -o pss main.o interface.o
main.o : main.c interface.h
interface.o : interface.c
pss is supposed to be the final executable file. However, the makefile does not create the executable pss. When I explicitly add the line for creating pss, then I am getting a linking error.
asheesh:~/Source$ make
gcc `pkg-config --cflags --libs gtk+-2.0` -o pss main.o interface.o
interface.o: In function `interface':
interface.c:(.text+0x1e): undefined reference to `gtk_init'
interface.c:(.text+0x28): undefined reference to `gtk_window_new'
interface.c:(.text+0x38): undefined reference to `gtk_widget_show'
interface.c:(.text+0x3d): undefined reference to `gtk_main'
collect2: ld returned 1 exit status
make: *** [pss] Error 1
How do I create the final executable file using make?
Changed the makefile to handle library dependencies properly. Still not working.
#Options for Development
CFLAGS = `pkg-config --cflags gtk+-2.0`
#Libraries
LIBS = `pkg-config --libs gtk+-2.0`
all: pss
pss : main.o interface.o
$(cc) $(LIBS) $(CFLAGS) -o pss main.o interface.o
main.o : main.c interface.h
$(cc) $(CFLAGS) -o main.o main.c interface.o
interface.o : interface.c
$(cc) $(CFLAGS) $(LIBS) -o interface.o interface.c
Looks like your compilation phase is not able to find include files. When I see how you built your .o files, there is no -I flag to indicate where to find gtk include files.
You may want to add suffix rules:
.SUFFIXES: .c .o
.c.o:
gcc -c `pkg-config --cflags gtk+-2.0` $<
I am not entirely sure what the problem was, but it got solved by manually specifying the compile commands.
# Compiler
cc = gcc
#Options for Development
CFLAGS = `pkg-config --cflags gtk+-2.0`
#Libraries
LIBS = `pkg-config --libs gtk+-2.0`
all: pss
pss : main.o interface.o
$(cc) -o pss main.o interface.o $(LIBS)
# $(cc) $(LIBS) -o pss main.o interface.o
# This line fails to link whereas the line above works.
main.o : main.c interface.h
$(cc) $(CFLAGS) -c main.c interface.c
interface.o : interface.c
$(cc) $(CFLAGS) -c interface.c
You've forgotten '-c' option while building .o files (in your first message).
You also don't need to include *.o or *.c files in compile phase:
$(cc) $(CFLAGS) -o main.o main.c interface.o // wrong
$(cc) $(CFLAGS) -c -o main.o main.c // right
and to your last code:
# Compiler
CC = gcc // Fixed: CAPSLOCK here
#Options for Development
CFLAGS = `pkg-config --cflags gtk+-2.0`
#Libraries
LIBS = `pkg-config --libs gtk+-2.0`
all: pss
pss : main.o interface.o
$(cc) -o pss main.o interface.o $(LIBS)
# $(cc) $(LIBS) -o pss main.o interface.o
# This line fails to link whereas the line above works.
main.o : main.c interface.h
$(CC) $(CFLAGS) -c main.c
interface.o : interface.c
$(CC) $(CFLAGS) -c interface.c
Also you can write 5 last lines even simpler:
main.o : main.c interface.h
interface.o : interface.c
No recipes needed because of the implicit rule for building .o from .c with recipe in a form:
$(CC) $(CPPFLAGS) $(CFLAGS) -c
So my task is simple, I have created the makefile (New with makefiles) and I want to keep my .o files in a different folder to have a cleaner directory and allow the usage of .o files by others.
I searched and found many solution pointing to using -o $< $#
However, it is giving me that g++: cannot specify -o with -c or -S with multiple files
This is what I want to do:
$(OBJECT_PATH)/file1.o: $(SOURCE_PATH)/file2.cpp $(SOURCE_PATH)/file1.cpp
$(CC) $(CFLAGS) $(SOURCE_PATH)/file2.cpp $(SOURCE_PATH)/file1.cpp -o $#
file1.cpp has #include "file1.h", so from what I read I should include file1.cpp in the dependencies. However, now I can't export to a different directory.
Is there a solution? Or do I have the concept wrong?
Use make -d or even better remake -x to understand what commands are invoked.
Run also make -p to understand what builtin rules are used.
We cannot help you more, because we have no idea if you redefined CFLAGS.
And C++ compilation should better be done with g++ that is CXX and CXXFLAGS, e.g. with (I am extracting this from my make -p output)
LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
CXX = g++
%.o: %.cc
$(COMPILE.cc) $(OUTPUT_OPTION) $<
I strongly suggest to have CXXFLAGS= -Wall -g at least during the development phase. Learn also to use gdb and valgrind.
You could have the following in your Makefile
CXXFLAGS= -g -Wall
SOURCES=f1.cc f2.cc
SOURCE_PATH=yoursourcedir/
OBJECT_PATH=yourobjectdir/
SRCFILES=$(patsubst %.cc,$(SOURCE_PATH)/%.cc,$(SOURCES))
OBJFILES=$(patsubst %.cc,$(OBJECT_PATH)/%.o,$(SOURCES))
PROGFILE=$(OBJECT_PATH)
.PHONY: all clean
all: $(PROGFILE)
$(PROGFILE): $(OBJFILES)
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $#
$(OBJECT_PATH)/%.o: $(SOURCE_PATH)/%.cc
$(COMPILE.cc) $(OUTPUT_OPTION) $<
clean:
$(RM) $(OBJECT_PATH)/*.o $(PROGFILE)
try
$(OBJECT_PATH)/file1.o: $(SOURCE_PATH)/file2.cpp $(SOURCE_PATH)/file1.cpp
$(CC) $(CFLAGS) $^ -c $#
and check that CFLAGS doesn't include -o -c or -s flags
also read about implicit rules. it might help you to orginzie your makefile