Here is my Makefile:
CC=gcc
CFLAGS=-Wall -std=gnu99
OBJ1=mknlrescs.o collisionsys.o csheader.o utils.o labels.o csdata.o
OBJ2=mknrescs.o utils.o
all: mknlrescs mknrescs
mknlrescs: $(OBJ1)
$(CC) $(CFLAGS) -o $# $<
mknrescs: $(OBJ2)
$(CC) $(CFLAGS) -o $# $<
%.o: %.c %.h
$(CC) $(CFLAGS) -c $<
When I type make mknlrescs I get the following:
$ make mknlrescs
gcc -Wall -std=gnu99 -c -o mknlrescs.o mknlrescs.c
gcc -Wall -std=gnu99 -c collisionsys.c
gcc -Wall -std=gnu99 -c csheader.c
gcc -Wall -std=gnu99 -c utils.c
gcc -Wall -std=gnu99 -c labels.c
gcc -Wall -std=gnu99 -c csdata.c
gcc -Wall -std=gnu99 -o mknlrescs mknlrescs.o -lm
mknlrescs.o: In function `main':
mknlrescs.c:(.text+0x4b): undefined reference to...
And a bunch of other "undefined reference to..." errors.
The rest of the objects are not being linked. Notice it only linked the first object file. How can I correct this?
The automatic variable $< stands for the first prerequisite of the rule that defined the recipe.
If you want to use ALL the prerequisites, use $^ instead.
See Automatic Variables for a full list.
Related
I've done this Makefile with the following structure:
BIN_FILES = array cliente servidor
CC = gcc
CCGLAGS = -Wall -g
all: CFLAGS=$(CCGLAGS)
all: $(BIN_FILES)
.PHONY : all
array.o: array.c array.h
$(CC) -c -Wall -fPIC array.c
cliente.o: cliente.c array.h
$(CC) -Wall -c cliente.c
cliente: cliente.o array.h
$(CC) -Wall -o cliente -ldl -lrt
servidor.o: servidor.c mensajes.h
$(CC) -Wall -c servidor.c -lrt -lpthread
servidor: servidor.o
$(CC) -o $# servidor -lrt -lpthread
clean:
rm -f $(BIN_FILES) *.o
.SUFFIXES:
.PHONY : clean
But when I try to execute it, it only works the first rule. Then the execution stops. My final objective is to make each rule work, because if I execute each rule separately it works:
gcc -c -Wall -fPIC array.c
gcc -fPIC -shared -o libarray.so array.o -lrt
gcc -Wall -o cliente cliente.c -ldl -lrt
gcc -Wall -o servidor servidor.c -lrt -lpthread
Thanks
Edit:
Now I obtain the following error applying #Jens modifications:
make: *** No rule to make the objective 'array', necesary for 'all'. Stop.
The targets for cliente.o and servidor.o should use -c instead of -o, i.e. you want to compile to object files.
There's also no point in specifying header files as dependencies in targets cliente and servidor. The commands for these only link, but don't compile files.
servidor: servidor.o
$(CC) -o $# servidor.o -lrt -lpthread
There's also no point is specifying library options -ldl etc when compiling to object files with -c.
cliente.o: cliente.c array.h
$(CC) -Wall -c cliente.c
I'm compiling KDBUS in my machine (x86-64, ubuntu 14.04). But this question is actually not related. This is a example. The first command fails, but the second succeeds. The success and failure depend on the order of -lm, and -lm. I saw this kinds of problem before. I could solved that problem manually. By this time, I want to know if there is a way to the first command succeeds without modifying the order of -lXXX ridiculously. Is there someone who know the way?
1.
gcc -L/usr/lib/x86_64-linux-gnu -std=gnu99 -Wall -Wextra -g -include /include/uapi/linux/memfd.h -I../samples/ -D_GNU_SOURCE -Wno-unused-parameter -Wmaybe-uninitialized -Wredundant-decls -Wcast-align -Wsign-compare -Wno-missing-field-initializers -pthread -lm -lcap kdbus-enum.o kdbus-util.o kdbus-test.o test-activator.o test-attach-flags.o test-benchmark.o test-bus.o test-chat.o test-connection.o test-daemon.o test-endpoint.o test-fd.o test-free.o test-match.o test-message.o test-metadata-ns.o test-monitor.o test-names.o test-policy.o test-policy-ns.o test-policy-priv.o test-sync.o test-timeout.o -o kdbus-test
kdbus-util.o: In function `do_cap_get_flag':
/harddisk/git/public/KDBUS/kdbus/test/kdbus-util.c:1525: undefined reference to `cap_get_flag'
kdbus-util.o: In function `test_is_capable':
/harddisk/git/public/KDBUS/kdbus/test/kdbus-util.c:1550: undefined reference to `cap_get_proc'
/harddisk/git/public/KDBUS/kdbus/test/kdbus-util.c:1570: undefined reference to `cap_free'
test-benchmark.o: In function `dump_stats':
/harddisk/git/public/KDBUS/kdbus/test/test-benchmark.c:62: undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
.2
gcc -L/usr/lib/x86_64-linux-gnu -std=gnu99 -Wall -Wextra -g -include /include/uapi/linux/memfd.h -I../samples/ -D_GNU_SOURCE -Wno-unused-parameter -Wmaybe-uninitialized -Wredundant-decls -Wcast-align -Wsign-compare -Wno-missing-field-initializers -pthread kdbus-enum.o kdbus-util.o -lcap kdbus-test.o test-activator.o test-attach-flags.o test-benchmark.o -lm test-bus.o test-chat.o test-connection.o test-daemon.o test-endpoint.o test-fd.o test-free.o test-match.o test-message.o test-metadata-ns.o test-monitor.o test-names.o test-policy.o test-policy-ns.o test-policy-priv.o test-sync.o test-timeout.o -o kdbus-test
Added 1.
kdbus-test: $(OBJS)
#echo ' TARGET_LD $#'
#echo $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $#
$(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $#
This is the makefile for the above compile command. I think that this kinds of makefiles are common. How should I modify this makefile to work?
Added 2.
kdbus-test: $(OBJS)
#echo ' TARGET_LD $#'
#echo $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $#
$(Q)$(CC) $(CFLAGS) $^ -o $# $(LDFLAGS)
After I added the above additional question, I found that this code works. After the comment from Mike Kinghan and this working code, is it the right way to put the $LDFLAGS after object files generally?
I am using the following makefile to build my project:
CC = /usr/bin/g++
CFLAGS = -Wall -pedantic -std=c++0x
LDFLAGS =
OBJ = main.o pnmhandler.o pixmap.o color.o
pnm: $(OBJ)
$(CC) $(CFLAGS) -o pnm $(OBJ) $(LDFLAGS)
%.o: %.c
$(CC) $(CFLAGS) -c $<
As I run make I get the following error:
/usr/include/c++/4.9.1/bits/c++0x_warning.h:32:2: error: #error This
file requires compiler and library support for the ISO C++ 2011
standard. This support is currently experimental, and must be enabled
with the -std=c++11 or -std=gnu++11 compiler options.
As I can read from the following line, the CFLAGS are not properly included, but I have no idea what I am doing wrong:
g++ -c -o main.o main.cpp
Also tried -std=c++11 and -std=gnu++11, without any results. Any ideas?
If I run make -Bn, I get:
g++ -c -o main.o main.cpp
g++ -c -o pnmhandler.o pnmhandler.cpp
g++ -c -o pixmap.o pixmap.cpp
g++ -c -o color.o color.cpp
/usr/bin/g++ -Wall -pedantic -std=c++0x -o pnm main.o pnmhandler.o pixmap.o color.o
EDIT: Replacing the rule %.o: %.c with %.o: %.cpp fixes my problem.
The reason you see
g++ -c -o main.o main.cpp
is that Make is invoking its standard rule to create the object file:
%.o: %.cpp
# recipe to execute (built-in):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
The command expands to
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $# $<
Instead of setting CC and CFLAGS in your makefile, you should set CXX and CXXFLAGS, which are meant for C++ rather than C. That allows the built-in rule above to work for you, and then you just need to make sure the right linker is used, e.g. with
pnm: LINK.o=$(LINK.cc)
pnm: $(OBJ)
You also don't need the %.o: %.c rule, as you have no C sources.
Complete Makefile:
CXX = /usr/bin/g++
CXXFLAGS = -Wall -pedantic -std=c++0x
OBJ = main.o pnmhandler.o pixmap.o color.o
pnm: LINK.o=$(LINK.cc)
pnm: $(OBJ)
clean::
$(RM) pnm
.PHONY: clean
I am trying to create a very basic hand crafted Makefile to create a shared library to illustrate a point.
This is what I have so far:
SHELL = /bin/sh
CC = gcc
FLAGS = -std=gnu99 -Iinclude
CFLAGS = -fPIC -pedantic -Wall -Wextra -march=native -ggdb3
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
TARGET = example.so
SOURCES = $(shell echo src/*.c)
HEADERS = $(shell echo include/*.h)
OBJECTS = $(SOURCES:.c=.o)
PREFIX = $(DESTDIR)/usr/local
BINDIR = $(PREFIX)/bin
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(FLAGS) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) $(OBJECTS)
When I run make, it attempts to build an application - and ld fails because it can't resolve main().
Problem seems to be with CFLAGS - I have specified -fPIC but that is not working - what am I doing wrong?
Edit
I added the -shared flag as suggested, when I run make, I got this error:
gcc -std=gnu99 -Iinclude -fPIC -shared -pedantic -Wall -Wextra -march=native -ggdb3 -O0 -D _DEBUG -o example.so src/example.o
/usr/bin/ld: src/example.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
src/example.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [example.so] Error 1
Which seems to be suggesting to revert back to -fPIC only.
BTW, my new CFLAGS setting is:
CFLAGS = -fPIC -shared -pedantic -Wall -Wextra -march=native -ggdb3
I am running gcc v4.4.3 on Ubuntu 10.0.4.
The solution was to modify the XXFLAGS as follows:
FLAGS = # -std=gnu99 -Iinclude
CFLAGS = -fPIC -g #-pedantic -Wall -Wextra -ggdb3
LDFLAGS = -shared
Compile with -shared:
gcc -o libfoo.so module1.o module2.o -shared
(This also works on MingW under Windows to produce DLLs.)
Example for C++ files. I've also included a clean target.
.PHONY : clean
CPPFLAGS= -fPIC -g
LDFLAGS= -shared
SOURCES = $(shell echo *.cpp)
HEADERS = $(shell echo *.h)
OBJECTS=$(SOURCES:.cpp=.o)
FIKSENGINE_LIBDIR=../../../../lib
FIKSENGINE_INCDIR=../../../../include
TARGET=$(FIKSENGINE_LIBDIR)/tinyxml.so
all: $(TARGET)
clean:
rm -f $(OBJECTS) $(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(CPPFLAGS) $(OBJECTS) -o $# $(LDFLAGS)
Since you try to build so file, you probably need -shared.
this is my goto makefile rule for so files:
%.so: %.o ; $(LINK.c) $(LDFLAGS) -shared $^ -o $#
can be used like so
CFLAGS+=-fPIC
libmyfoo.so: # create from libmyfoo.o
# or
libmyfoo.so: myfoo.o # create from myfoo.o
I downloaded someone's source code for a program and i needed to make some changes.
Now i want to compile it but it doesn't seem to work.
PROGS = isotociso
COMMON = tools.o bn.o ec.o wiidisc.o rijndael.o
DEFINES = -DLARGE_FILES -D_FILE_OFFSET_BITS=64
LIBS = C:/Dev-Cpp/lib/libwsock32.a C:/Dev-Cpp/lib/libcrypto.a C:/Dev-Cpp/lib/libcomdlg32.a
CC = gcc
#CFLAGS = -Wall -W -Os -Ilibwbfs -I.
CFLAGS = -Wall -m32 -W -ggdb -Ilibwbfs -I.
LDFLAGS = -m32 -static
VPATH+=libwbfs
OBJS = $(patsubst %,%.o,$(PROGS)) $(COMMON)
all: $(PROGS)
$(PROGS): %: %.o $(COMMON) Makefile
$(CC) $(CFLAGS) $(LDFLAGS) $< $(COMMON) $(LIBS) -o $#
$(OBJS): %.o: %.c tools.h Makefile
$(CC) $(CFLAGS) $(DEFINES) -c $< -o $#
clean:
-rm -f $(OBJS) $(PROGS)
Output
C:\Users\Panda\Desktop\uloader_v4.1\src\isotociso\src>make
gcc -Wall -m32 -W -ggdb -Ilibwbfs -I. -DLARGE_FILES -D_FILE_OFFSET_BITS=64 -c i
sotociso.c -o isotociso.o
process_begin: CreateProcess((null), gcc -Wall -m32 -W -ggdb -Ilibwbfs -I. -DLAR
GE_FILES -D_FILE_OFFSET_BITS=64 -c isotociso.c -o isotociso.o, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [isotociso.o] Error 2
What would be the problem?
Looks to me as if gcc is not in your PATH.
It also looks like you need MinGW to get the libraries.
I am no expert in C(++) development under Windows, but my interpretation would be that it can't find the compiler itself. What development environment are you using?
It looks like it can't find a file. Are you sure you have all the required source files?