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?
Related
I have a phony debug and asm target. debug works by updating the variable CFLAGS and then compiles the normal target, which uses these new CFLAGS to produce debug symbols. This works as intended.
Analogously I want to define the asm target set the -S switch and to change the output name from file to file.s. However, the last part does not work, and I get:
$ make asm -B
gcc -fmessage-length=0 -ansi -pedantic -Werror -Wall -Wextra -Wwrite-strings -Winit-self -Wcast-align -Wcast-qual -Wpointer-arith -Wstrict-aliasing -Wformat=2 -Wmissing-declarations -Wmissing-include-dirs -Wno-unused-parameter -Wuninitialized -Wold-style-definition -Wstrict-prototypes -Wmissing-prototypes -Wdouble-promotion -S -masm=intel file.c -o file
notice the last part [..] -S -masm=intel file.c -o file with the extra parameters but without the .s extension.
What am I missing?
Makefile:
TARGET=file
SOURCE=*.c
HEADERS=*.h
TESTS=*.sh
PROJECT=$(TARGET) $(SOURCE) $(HEADERS) $(TESTS) Makefile
CC=gcc
CFLAGS=\
-ansi \
-pedantic \
-Wall \
# makefile-rules that don't produce files directly
.PHONY: default all debug asm
default: $(TARGET)
# Compile
$(TARGET): $(SOURCE) $(HEADERS) $(TESTS)
$(CC) $(CFLAGS) $< -o $#
debug: CFLAGS += -DDEBUG -ggdb
debug: $(TARGET)
asm: CFLAGS +=-S -masm=intel
asm: TARGET +=.s <------------------ THIS LINE !!!!!!
asm: $(TARGET)
You could just add a $(TARGET).s target to the rule and use that in asm:
$(TARGET) $(TARGET).s: $(SOURCE) $(HEADERS) $(TESTS)
$(CC) $(CFLAGS) $< -o $#
asm: CFLAGS += -S -masm=intel
asm: $(TARGET).s
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.
Following makefile:
#Regular c++ rules
CXX=g++
CXXFLAGS=-Wall -march=native -ffast-math -O3
CXX_OBJECTS=AbsNode.o rle16.o rle8.o
# Link command:
test : $(CXX_OBJECTS)
$(CXX) $(CXX_OBJECTS) -o test
# Compilation commands:
$.o : %.cpp
$(CXX) -c $< $(CXXFLAGS) -o $#
Outputs
g++ -Wall -march=native -ffast-math -O3 -c -o AbsNode.o AbsNode.cpp
g++ -Wall -march=native -ffast-math -O3 -c -o rle16.o rle16.cpp
g++ -Wall -march=native -ffast-math -O3 -c -o rle8.o rle8.cpp
while I expect
g++ -c AbsNode.cpp -Wall -march=native -ffast-math -O3 -o AbsNode.o
g++ -c rle16.cpp -Wall -march=native -ffast-math -O3 -o rle16.o
g++ -c rle8.cpp -Wall -march=native -ffast-math -O3 -o rle8.o
Why is the order of arguments to g++ switched compared to the rule stated in makefile???
$.o : %.cpp
You typed $ instead of %, which turned is into a non-template rule. However make has a default rule for C++ file, which was taken instead of yours. The order of arguments match this internal rule.
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?