How to use gcc to compile multiple files - gcc

I have several files needed to be compiled.
here is the command. the sample_client.c dependent on the lsp.o. Now I changed the lsp.c and lsp.h. How can I compile to get this change effective to lsp.o?
the main function is in the sample_client.c, lsp.c does not have a main function.
gcc -g -I/usr/include -g sample_client.c lsp.o lspmessage.pb-c.o -o sample_client -L/usr/lib -lprotobuf-c
Here is my makefile,
CC = gcc
TARGET = sample_client sample_server
CFLAGS += -g -I/usr/include
LDFLAGS += -g -lprotobuf-c -L/usr/lib
all: $(TARGET)
$(TARGET): lsp.o lspmessage.pb-c.o
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $#
clean:
rm -f *.o
rm -f $(TARGET)
However, the lprotobuf-c can not be correctly linked.
run make -f Makefile
I can get the following,
lspmessage.pb-c.o: In function `lspmessage__get_packed_size':
...: undefined reference to `protobuf_c_message_get_packed_size'
lspmessage.pb-c.o: In function `lspmessage__pack':
...: undefined reference to `protobuf_c_message_pack'
I know that I can run this command,
gcc -g -I/usr/include -g sample_client.c lsp.o lspmessage.pb-c.o -o sample_client -L/usr/lib -lprotobuf-c
But what if I change the lsp.c and lsp.h ?

It looks to me like your LDFLAGS isn't correct. Try the following:
LDFLAGS += -L/usr/lib -lprotobuf-c
It looks like you had the directory -L and the library out of order.
Also, I removed the additional call to -g for you.

Related

Makefile - include files not found when building with multiple source files

I have a make file:
# Makefile
CC = gcc
SRC = pixel.c
TARGET = pixel.exe
OBJECTS = bmp.o pixel.o
#CFLAGS_W = -Wall -Wl,-subsystem,windows
CFLAGS_W = -Wall
LFLAGS_W = -lSDL2
INCS_W = -I.\SDL2\include
LIBS_W = -L.\SDL2\lib\x64
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -o $(TARGET) $(OBJECTS)
it will build bmp.c, but when it tries to build pixel.c I get the error:
pixel.c:6:10: fatal error: SDL.h: No such file or directory
however, pixel.c has been building fine all the time I was just building it on its own (before I added bmp.c), using the command:
all:
$(CC) $(SRC) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -o $(TARGET)
I really struggle with makefiles because I just don't use them enough, but this doesn't really feel like a "make" problem.
I'm using mingw32-make and gcc in a windows sandbox.
EDIT:
I have added
.c.o:
$(CC) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -c $< -o $#
to my makefile, which gets me a step further (I think), but now complains that all of the SDL functions are undefined
C:\Users\WDAGUtilityAccount\Desktop\Projects\Pixel>mingw32-make
gcc -I./SDL2/include -L./SDL2/lib/x64 -Wall -lSDL2 -g -c bmp.c -o bmp.o
gcc -I./SDL2/include -L./SDL2/lib/x64 -Wall -lSDL2 -g -c pixel.c -o pixel.o
gcc -I./SDL2/include -L./SDL2/lib/x64 -Wall -lSDL2 -g -o pixel.exe bmp.o pixel.o
pixel.o: In function `main':
C:\Users\WDAGUtilityAccount\Desktop\Projects\Pixel/pixel.c:119: undefined reference to `SDL_Init'
C:\Users\WDAGUtilityAccount\Desktop\Projects\Pixel/pixel.c:121: undefined reference to `SDL_GetError'
C:\Users\WDAGUtilityAccount\Desktop\Projects\Pixel/pixel.c:126: undefined reference to `SDL_CreateWindow'
C:\Users\WDAGUtilityAccount\Desktop\Projects\Pixel/pixel.c:131: undefined reference to `SDL_GetError'
...
I can get the whole project to compile if I just do this on its own:
SRC = bmp.c pixel.c
...
test:
$(CC) $(SRC) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -o $(TARGET)
which is fine, it'll do, but it rebuilds everything every time, and I'd like to know why it isn't working anyway :)

adding shared library path to Makefile

I want to add the shared library path to my Makefile. I have put in the export command in the makefile, it even gets called, but I still have to manually export it again.
What is the correct approach?
Makefile:
SOURCES = kwest_main.c fusefunc.c dbfuse.c logging.c dbbasic.c dbinit.c dbkey.c metadata_extract.c plugins_extraction.c import.c
LIBS = -L$(LIB) -lfuse -lsqlite3 -lkw_taglib -ltag_c -ltag -Wl,-rpath=.
INCLUDE = ../include
LIB = ../lib
EXE = kwest
CC = gcc
CCFLAGS = -g -Wall -Wextra -std=gnu99 -pedantic-errors -I$(INCLUDE)
OFLAGS = -c
ARCH = $(shell getconf LONG_BIT)
X = -D_FILE_OFFSET_BITS=$(ARCH)
OBJECTS = $(SOURCES:.c=.o)
$(EXE) : $(OBJECTS)
$(CC) -o $(EXE) $(OBJECTS) $(LIBS)
%.o: %.c
$(CC) $(OFLAGS) $(CCFLAGS) $<
fusefunc.o: fusefunc.c
$(CC) $(OFLAGS) $(CCFLAGS) $< $X
kwest_libs: kw_taglib
--->export LD_LIBRARY_PATH=$(LIB):$LD_LIBRARY_PATH
kw_taglib: plugin_taglib
plugin_taglib: plugin_taglib.o kwt_upd_meta.o
gcc -g -shared -I$(INCLUDE) -Wl,-soname,libkw_taglib.so -o $(LIB)/libkw_taglib.so -ltag -ltag_c plugin_taglib.o kwt_upd_meta.o
plugin_taglib.o:
gcc -c -g -I$(INCLUDE) -Wall -Wextra -pedantic-errors -std=gnu99 -fPIC -ltag_c -c plugin_taglib.c
kwt_upd_meta.o:
g++ -c -g -I$(INCLUDE) -Wall -Wextra -pedantic-errors -fPIC -ltag kwt_upd_meta.cpp
c: clean
clean:
rm -rf *.o
rm -rf *.db
ca: cleanall
cleanall: clean
rm -rf $(EXE)
ob: cleanall
rm -rf ~/.config/$(EXE)/
Execution:
$ ./kwest mnt
./kwest: error while loading shared libraries: libkw_taglib.so: cannot open shared object file: No such file or directory
$ export LD_LIBRARY_PATH=../lib:D_LIBRARY_PATH
$ ./kwest mnt
"executes correctly"
The usual way is to copy the dynamic library during the default make and to one of the standard library path
/usr/local/bin
or one of your project library path and add the library to executable using
-L/project/specific/path
during make install.
As already mentioned here, the thing you probably want is the linker option -rpath.
Like that, you can set a default search path for the binary. Looks like you even already use -rpath in your makefile, but you specify the wrong path:
LIBS = -L$(LIB) -lfuse -lsqlite3 -lkw_taglib -ltag_c -ltag -Wl,-rpath=.
So the binary will search in the current directory for dyn-libraries.
However, you add ../lib to your LD_LIBRARY_PATH later, for execution of the binary, so the given path . seems to be wrong.
Please take a try for the following fix:
LIBS = -L$(LIB) -lfuse -lsqlite3 -lkw_taglib -ltag_c -ltag -Wl,-rpath=../lib
Like that you should not need to specify a LD_LIBRARY_PATH for execution.

Why does make delete my temporary files?

I have a simple Makefile,
.PHONY: clean
PROGRAMS=$(patsubst main%.cpp,example%,$(wildcard main*.cpp))
all: ${PROGRAMS}
GCCVERSION=$(shell gcc -dumpversion)
GLCFLAGS=$(shell pkg-config --cflags gl)
CPPFLAGS=-Wall -O2 ${GLCFLAGS}
ifeq "${GCCVERSION}" "4.5.2"
CXXFLAGS=-std=c++0x
else
CXXFLAGS=-std=c++11
endif
GLLIBS=$(shell pkg-config --libs gl)
LIBS=${GLLIBS} -lglut
example%: main%.o shaders.o fileutils.o
${CXX} $^ ${LIBS} -o $#
clean:
rm -f *.o ${PROGRAMS}
But when I executed it, it delete the *.o files as last command. I don't know why:
$ make
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o main01.o main01.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o shaders.o shaders.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o fileutils.o fileutils.cpp
g++ main01.o shaders.o fileutils.o -lGL -lglut -o example01
rm main01.o fileutils.o shaders.o
Is there anything wrong with my Makefile?
Intermediate files are deleted by design: see Chained Rules in GNU make manual.
Use .SECONDARY or .PRECIOUS targets to keep your precioussss temp files.
Just to clarify the previous response, you need to add a special rule like
.PRECIOUS: myfile.o

Creating a simple Makefile to build a shared library

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

Compiling error

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?

Resources