I am working on a project that uses some code written by someone else inside a folder called CommandParser. My project is called TCP_IP and inside it there is the CommandParser folder.
This is my makefile.
TARGET = $(BIN_DIR)/sim_tcp_ip
LIBS = -lpthread -L ./CommandParser -lcli
OBJS = $(OBJ_DIR)/prueba.o \
$(OBJ_DIR)/ListaEnlazada.o \
$(OBJ_DIR)/Grafico.o \
$(OBJ_DIR)/Net.o \
$(OBJ_DIR)/Topologias.o
BIN_DIR = ./bin
OBJ_DIR = ./obj
INC_DIR = ./inc
SRC_DIR = ./src
CFLAGS = -Wall -I$(INC_DIR)
$(TARGET): $(OBJS) CommandParser/libcli.a
mkdir -p $(BIN_DIR)
gcc $(CFLAGS) $(OBJS) -o $(TARGET) $(LIBS)
$(OBJ_DIR)/%.o : %.c
mkdir -p $(OBJ_DIR)
gcc -c -MD $(CFLAGS) $< -o $#
CommandParser/libcli.a:
(cd CommandParser; make)
-include $(OBJ_DIR)/*.d
.PHONY: clean
clean:
rm -rf $(OBJ_DIR) $(BIN_DIR)
(cd CommandParser; make clean)
all:
make
(cd CommandParser; make)
CommandParser has its own makefile.
CC=gcc
CFLAGS=-g -Wall
INCLUDES=-I .
CLILIB=libcli.a
TARGET:exe ${CLILIB}
OBJ=cmd_hier.o parser.o serialize.o string_util.o clistd.o clicbext.o gluethread/glthread.o ut/utinfra/ut_parser.o
exe:testapp.o ${CLILIB}
#echo "Building final executable"
# ${CC} ${CFLAGS} ${INCLUDES} testapp.o -o exe -L . -lcli -lpthread -lrt
cmd_hier.o:cmd_hier.c
#echo "Building cmd_hier.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} cmd_hier.c -o cmd_hier.o
parser.o:parser.c
#echo "Building parser.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} parser.c -o parser.o
gluethread/glthread.o:gluethread/glthread.c
#echo "Building gluethread/glthread.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} gluethread/glthread.c -o gluethread/glthread.o
serialize.o:serialize.c
#echo "Building serialize.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} serialize.c -o serialize.o
string_util.o:string_util.c
#echo "Building string_util.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} string_util.c -o string_util.o
clistd.o:clistd.c
#echo "Building clistd.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} clistd.c -o clistd.o
clicbext.o:clicbext.c
#echo "Building clicbext.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} clicbext.c -o clicbext.o
testapp.o:testapp.c
#echo "Building testapp.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} testapp.c -o testapp.o
ut/utinfra/ut_parser.o:ut/utinfra/ut_parser.c
#echo "Building ut/utinfra/ut_parser.o"
# ${CC} ${CFLAGS} -c ${INCLUDES} ut/utinfra/ut_parser.c -o ut/utinfra/ut_parser.o
${CLILIB}: ${OBJ}
#echo "Building Library ${CLILIB}"
ar rs ${CLILIB} ${OBJ}
clean:
rm -f exe
rm -f *.o
rm -f gluethread/*.o
rm -f ut/utinfra/*.o
rm -f ${CLILIB}
rm -f CMD_HIST_RECORD_FILE.txt
install:
cp ${CLILIB} /usr/local/lib/
cp libcli.h /usr/include/
cp cmdtlv.h /usr/include/
uninstall:
rm -f /usr/local/lib/${CLILIB}
rm -f /usr/include/libcli.h
rm -f /usr/include/cmdtlv.h
When do make inside CommandParser, I don't get any error. However, something seems to be wrong with my makefile because if I do make in my TCP_IP folder, I get some undefined reference errors.
/usr/bin/ld: ./CommandParser/libcli.a(ut_parser.o): en la función ut_parser_init': /home/darinel/Documentos/Cursos/C++/TCP_IP/CommandParser/ut/utinfra/ut_parser.c:52: referencia a mq_open' sin definir
/usr/bin/ld: ./CommandParser/libcli.a(ut_parser.o): en la función run_test_case': /home/darinel/Documentos/Cursos/C++/TCP_IP/CommandParser/ut/utinfra/ut_parser.c:261: referencia a mq_timedreceive' sin definir
/usr/bin/ld: ./CommandParser/libcli.a(ut_parser.o): en la función cli_out': /home/darinel/Documentos/Cursos/C++/TCP_IP/CommandParser/ut/utinfra/ut_parser.c:517: referencia a mq_send' sin definir
collect2: error: ld returned 1 exit status
make: [makefile:16: bin/sim_tcp_ip] Error 1
The message shows that these errors come from the CommandParser code, and not from my code, even though it previously worked fine in the CommandParser folder.
It appears that the CommandParser library is looking for another library, that contains functions like mq_open, mq_send, and mq_timedreceive. If you look up these functions you'll see that they're provided by the realtime library, librt. So, you need to add the -lrt option to your link line.
Also, please pay close attention to the order of libraries on the link line. You should always order them highest-level to lowest-level. You have:
LIBS = -lpthread -L ./CommandParser -lcli
but -lpthread is a lower-level library so it should come after -lcli. Also, the modern way of building executables using threads is to use the -pthread option on BOTH the compile line AND the link line, so you should use:
LIBS = -pthread -L ./CommandParser -lcli -lrt
CFLAGS = -pthread -Wall -I$(INC_DIR)
Related
I'm trying to compile my C project using clang (I'm on MacOS Monterry) and a Makefile, but I keep getting the same error from clang in the command line:
> make
gcc -c src/ji.c src/main.c -o src/ji.o
clang: error: cannot specify -o when generating multiple output files
make: *** [src/ji.o] Error 1
These are the only files I have in the project so far:
src/main.c
src/ji.c
include/ji.h
The Makefile looks like this:
cc = gcc
src = $(wildcard src/*.c)
obj = $(src:.c=.o)
exec = ji
$(exec): $(obj)
$(cc) -Iinclude $< -o build/$#
%.o: %.c
$(cc) -c $(src) -o $#
clean:
-rm src/*.o
-rm ji
From YouTube videos I've seen, this should be the ideal Makefile for the project but no matter what I change I get the error.
There are a few issues:
-Iinclude needs to be on the %.o: %.c rule command
In %.o: %.c, we don't want $(src) but rather $<
We want patsubst to get the .o list obj
The $(exec) target doesn't match the -o option
The clean doesn't match the placement of the executable
Here's a refactored version (e.g. one way to do this--there are others):
cc = gcc
src = $(wildcard src/*.c)
obj = $(patsubst %.c,%.o,$(src))
exec = build/ji
$(exec): $(obj)
mkdir -p build
$(cc) $^ -o $#
%.o: %.c
$(cc) -c $< -o $# -Iinclude
clean:
rm -f src/*.o
rm -fr build
Here's the output of make:
gcc -c src/ji.c -o src/ji.o -Iinclude
gcc -c src/main.c -o src/main.o -Iinclude
mkdir -p build
gcc src/ji.o src/main.o -o build/ji
Here's the output of make clean:
rm -f src/*.o
rm -fr build
I'm trying to make a custom OS for the raspberry pi. I follow this tutorial and used their Makefile, but when I try to compile it, I get this error:
echo objects/kernel.o objects/uart.o objects/stdio.o objects/stdlib.o objects/boot.o
objects/kernel.o objects/uart.o objects/stdio.o objects/stdlib.o objects/boot.o
./gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc -T linker.ld -o kernel.img -ffreestanding -O2 -nostdlib objects/kernel.o objects/uart.o objects/stdio.o objects/stdlib.o objects/boot.o
process_begin: CreateProcess(NULL, ./gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc -T linker.ld -o kernel.img -ffreestanding -O2 -nostdlib objects/kernel.o objects/uart.o objects/stdio.o objects/stdlib.o objects/boot.o, ...) failed.
make (e=2): Das System kann die angegebene Datei nicht finden. (Translation: The system can't find the given file)
Makefile:33: recipe for target 'build' failed
mingw32-make: *** [build] Error 2
and the Makefile:
# Don't use normal gcc, use the arm cross compiler
CC = ./gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc
# Set any constants based on the raspberry pi model. Version 1 has some differences to 2 and 3
ifeq ($(RASPI_MODEL),1)
CPU = arm1176jzf-s
DIRECTIVES = -D MODEL_1
else
CPU = cortex-a7
endif
CFLAGS= -mcpu=$(CPU) -fpic -ffreestanding $(DIRECTIVES)
CSRCFLAGS= -O2 -Wall -Wextra
LFLAGS= -ffreestanding -O2 -nostdlib
# Location of the files
KER_SRC = ../src/kernel
KER_HEAD = ../include
COMMON_SRC = ../src/common
OBJ_DIR = objects
KERSOURCES = $(wildcard $(KER_SRC)/*.c)
COMMONSOURCES = $(wildcard $(COMMON_SRC)/*.c)
ASMSOURCES = $(wildcard $(KER_SRC)/*.S)
OBJECTS = $(patsubst $(KER_SRC)/%.c, $(OBJ_DIR)/%.o, $(KERSOURCES))
OBJECTS += $(patsubst $(COMMON_SRC)/%.c, $(OBJ_DIR)/%.o, $(COMMONSOURCES))
OBJECTS += $(patsubst $(KER_SRC)/%.S, $(OBJ_DIR)/%.o, $(ASMSOURCES))
HEADERS = $(wildcard $(KER_HEAD)/*.h)
IMG_NAME=kernel.img
build: $(OBJECTS) $(HEADERS)
echo $(OBJECTS)
$(CC) -T linker.ld -o $(IMG_NAME) $(LFLAGS) $(OBJECTS)
$(OBJ_DIR)/%.o: $(KER_SRC)/%.c
mkdir -p $(#D)
$(CC) $(CFLAGS) -I$(KER_SRC) -I$(KER_HEAD) -c $< -o $# $(CSRCFLAGS)
$(OBJ_DIR)/%.o: $(KER_SRC)/%.S
mkdir -p $(#D)
$(CC) $(CFLAGS) -I$(KER_SRC) -c $< -o $#
$(OBJ_DIR)/%.o: $(COMMON_SRC)/%.c
mkdir -p $(#D)
$(CC) $(CFLAGS) -I$(KER_SRC) -I$(KER_HEAD) -c $< -o $# $(CSRCFLAGS)
clean:
rm -rf $(OBJ_DIR)
rm $(IMG_NAME)
run: build
qemu-system-arm -m 1024 -M raspi2 -serial stdio -kernel kernel.img
But because I've never worked with Makefiles before, I don't know what is wrong with the Makefile
I am using pro*c in AIX,I want make my .pc file compile to a .so libary. And link it. This is my directory:
ls
connect.pc func.c get_log.pc main.c makefile sql_err.pc
This is my makefile:
#Makefile
CC = cc -g -brtl
CFLAGS = -g -c
ESQL = proc
RM = rm -f
MYHOME = /home/xxx
OBJ = main.o func.o
LIBOBJ = get_log.o connect.o sql_err.o
DBINC = -I$(ORACLE_HOME)/precomp/public
DBLIB = -L$(ORACLE_HOME)/lib -lclntsh
INCLUDE = -I$(MYHOME)/include
.SUFFIXES: .pc .c .o
.pc.o:
$(ESQL) include=$(MYHOME)/include iname=$*.pc
$(CC) -o $*.o $(CFLAGS) $*.c $(INCLUDE) $(DBINC) $(DBLIB)
$(RM) $*.c
$(RM) $*.lis
libmydb.so:$(LIBOBJ)
$(CC) -qmkshrobj -o $# $(LIBOBJ) $(DBLIB)
mv $# $(MYHOME)/lib
query:$(OBJ)
cc -o $# $(OBJ) -L$(MYHOME)/lib -lmydb
mv $# $(MYHOME)/bin
func.o:func.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
main.o:main.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
clean:
rm -f *.o *.lis
when I make I get this:
.......
cc -g -brtl -o sql_err.o -g -c sql_err.c -I/home/xxx/include -I/oracle/product/10.2.0/precomp/public -L/oracle/product/10.2.0/lib -lclntsh
rm -f sql_err.c
rm -f sql_err.lis
cc -g -brtl -qmkshrobj -o libmydb.so get_log.o connect.o sql_err.o -L/oracle/product/10.2.0/lib -lclntsh
mv libmydb.so /home/xxxlib
when it done mv libmydb.so ,it exit!!!without wrong message.why?? I also need my .c to compile to .o and finally to an executable file query link libmydb.so.
when I change the squeuce like this put .c.o before .pc.o:
query:$(OBJ)
cc -o $# $(OBJ) -L$(MYHOME)/lib -lmydb
mv $# $(MYHOME)/bin
func.o:func.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
main.o:main.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
.pc.o:
$(ESQL) include=$(MYHOME)/include iname=$*.pc
$(CC) -o $*.o $(CFLAGS) $*.c $(INCLUDE) $(DBINC) $(DBLIB)
$(RM) $*.c
$(RM) $*.lis
libmydb.so:$(LIBOBJ)
$(CC) -qmkshrobj -o $# $(LIBOBJ) $(DBLIB)
mv $# $(MYHOME)/lib
it give this message,although I have libmydb.so last step:
prepaid(wmfe)/home/xxx/src>make
cc -g -brtl -c -g -c main.c -I/home/xxx/include
cc -g -brtl -c -g -c func.c -I/home/xxx/include
cc -o query main.o func.o -L/home/xxx/lib -lmydb
ld: 0706-006 Cannot find or open library file: -l mydb
ld:open(): A file or directory in the path name does not exist.
make: 1254-004 The error code from the last command is 255.
Stop.
I can't handle this ,very strange,Help!!
By default make will make the first rule in your makefile, but it must not start with a dot. So the default rule in your makefile is libmydb.so and that is being built.
That rule is only dependent on the LIBOBJ and OBJ is not a dependency so it doesn't care about those. It doesn't exit with no reason, it exits because it has done the job you defined for it. There is no error to report.
If you change the order then the default rule is changed and it tries to compile query. This has no dependencies to the library, so it doesn't try to compile that.
If you want to compile everything you should have, for example, a rule all that lists the dependencies. In this case probably libmydb.so and query at least, in correct order. If this is the first rule it will be the default and your compilation will succeed.
I have an makefile but doesn't work. The error in terminal is this: cc -shared -o build/liblcthw.so src/lcthw/list.o
/usr/bin/ld: src/lcthw/list.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
src/lcthw/list.o: error adding symbols: Bad value
I need help to put the gcc comand gcc -shared -o target.so -fPIC target.c, i don't how to put the target.c instead list.o
This is the makefile:
CFLAGS=-g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local
SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=build/liblcthw.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
# The Target Build
all: $(TARGET) $(SO_TARGET) tests
dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all
$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
ar rcs $# $(OBJECTS)
ranlib $#
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
build:
#mkdir -p build
#mkdir -p bin
# The Unit Tests
.PHONY: tests
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
sh ./tests/runtests.sh
valgrind:
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
# The Cleaner
clean:
rm -rf build $(OBJECTS) $(TESTS)
rm -f tests/tests.log
find . -name "*.gc*" -exec rm {} \;
rm -rf `find . -name "*.dSYM" -print`
# The Install
install: all
install -d $(DESTDIR)/$(PREFIX)/lib/
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
# The Checker
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
check:
#echo Files with potentially dangerous functions.
#egrep $(BADFUNCS) $(SOURCES) || true
Your objects for liblcthw.a are built with -fPIC. Objects for liblcthw.so are not built with this setting.
Try changing rule:
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
to:
$(SO_TARGET): $(TARGET)
$(CC) -shared -o $# $^
Since the required objects are already in liblcthw.a.
Or, alternatively:
$(SO_TARGET): CFLAGS += -fPIC
$(SO_TARGET): $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
I'm having problem reported as below while trying to execute it. Where should I go to let it know where to find the .so lib which is under ${HOME}/projects/OpenImageIO/dist/linux64/lib?
Starting: /home/chaoren/Dropbox/hw2/hw2_3
/home/chaoren/Dropbox/hw2/hw2_3: error while loading shared libraries: libOpenImageIO.so.1.2: cannot open shared object file: No such file or directory
I built this project by importing my Makefile
OFILES = Matrix.o LinearAlgebra.o PerlinNoise.o Camera.o OIIOFiles.o Image.o Utilities.o Grid.o SparceGrid.o VolumeOperations.o Ray.o Face.o Line.o Lights.o Group.o PolySurf.o File.o OBJFile.o Vector.o
AFILES = $(OFILES)
ROOTDIR = .
LIB = $(ROOTDIR)/libVR.a
LINKS = Magick++-config --cppflags --cxxflags --ldflags --libs -lm -lOpenImageIO -L/usr/local/lib -L${HOME}/projects/OpenImageIO/dist/linux64/lib
INCLUDES = Magick++-config --cppflags --cxxflags -I${HOME}/projects/OpenImageIO/dist/linux64/include
CXX = g++ -Wall -g -O2 -D_THREAD_SAFE -pthread -fopenmp
.C.o:
$(CXX) -c $(INCLUDES) $<
all: $(AFILES)
ar rv $(LIB) $?
hw2_1: hw2_1.C
$(CXX) hw2_1.C $(INCLUDES) $(LIB) $(LINKS) -o hw2_1
hw2_2: hw2_2.C
$(CXX) hw2_2.C $(INCLUDES) $(LIB) $(LINKS) -o hw2_2
hw2_3: hw2_3.C
$(CXX) hw2_3.C $(INCLUDES) $(LIB) $(LINKS) -o hw2_3
noiseimage: noiseimage.C
$(CXX) noiseimage.C $(INCLUDES) $(LIB) $(LINKS) -o noiseimage
clean:
rm -f *.o *.gch core $(LIB) vr vrppm *~ vRender hw2_1 hw_2 hw2_3
KDevelop4 uses CMake as its default build system. In CMake all libraries and other program elements are identified in special file (CMakeLists.txt). That file then becomes the basis of the make file that actually builds the executable.