Creating static library in a makefile, using linux g++ compiler - c++

I have simple files:
hello.h , hello.cpp
I have created a makefile in order to generate a static library (libhello.a)
but I'm getting error message , what am I doing wrong?
My code is:
CC = g++
CFLAGS = -Wall -g
utilObjs = hello.o
libhello.a: $(utilObjs)
ar rc $# $(utilObjs)
ranlib $#
hello: hello.o libhello.a
$(CC) $(CFLAGS) hello.o -L ./ -lutil -o $#
hello.o: hello.cpp hello.h
$(CC) $(CFLAGS) -c $>
clean:
rm -rf *.o libhello.a hello
all: hello
.PHONY: all clean
The error message :
g++: fatal error: no input files
compilation terminated

I don't think $> means anything special, change it to $< , which expands to the first prerequisite of the rule. (hello.cpp in this case)

Related

no rule to make target 'Main.o', needed by 'Main' . Stop

Note: Unlike other Questions, this one is missing an obj file instead of a cpp file
I have a Directory called /Profiler
that got the following files:
Main.cpp
Draw.cpp
Draw.h (used in both cpp files)
Makefile
I created the following Makefile:
CC := g++
CCOPTS=-Wall -Wextra -O3 -std=c++17
Main_DEP_OBJ := Main.o Draw.o
Header:=Draw.h
all: main
%.o: %.C DEPS $(Header)
$(CC) ${CCOPTS} -c -o $# $<
Main: $(Main_DEP_OBJ)
${CC} ${CCOPTS} -o main $^
clean:
rm -f Main *.o
using the make command in Ubuntu gives me this error:
no rule to make target 'Main.o', needed by 'Main' . Stop.
You dont have a target rule for Main, or building .o file from the .cpp file.
CC := g++
CCOPTS=-Wall -Wextra -O3 -std=c++17
Main_DEP_OBJ := Main.o Draw.o
Header:=Draw.h
all: Main
%.o: %.cpp $(Header)
$(CC) ${CCOPTS} -c -o $# $<
Main: $(Main_DEP_OBJ)
${CC} ${CCOPTS} -o Main $^
clean:
rm -f Main *.o

Building shared libraries with Makefile

I have a project that I want to build a shared library for it. The following Makefile works:
libfastpd.so: fastpd.cpp
$(CXX) -std=c++11 -fPIC -c fastpd.cpp -o fastpd.o
$(CXX) -std=c++11 -fPIC -c graph.cpp -o graph.o
$(CXX) -std=c++11 -fPIC -c LinkedBlockList.cpp -o LinkedBlockList.o
$(CXX) -std=c++11 -fPIC -c maxflow.cpp -o maxflow.o
$(CXX) -std=c++11 -shared -Wl,-soname,libfastpd.so -o libfastpd.so fastpd.o graph.o LinkedBlockList.o maxflow.o
clean:
rm *.o *.so
Then I came across this recipe in Cogswell et al.'s C++ Cookbook: https://www.oreilly.com/library/view/c-cookbook/0596007612/ch01s18.html
and decided to improve my Makefile based on that:
# Specify extensions of files to delete when cleaning
CLEANEXTS = o so
# Specify the source files, the target files,
# and the install directory
SOURCES = fastpd.cpp graph.cpp LinkedBlockList.cpp maxflow.cpp
OUTPUTFILE = libfastpd.so
INSTALLDIR = ./
.PHONY: all
all: $(OUTPUTFILE)
# Build lib*.so from all the *.o;
# subst is the search-and-replace
# function demonstrated in Recipe 1.16
$(OUTPUTFILE): $(subst .cpp,.o,$(SOURCES))
$(CXX) -shared -fPIC $(LDFLAGS) -o $# $^
.PHONY: install
install:
mkdir -p $(INSTALLDIR)
cp -p $(OUTPUTFILE) $(INSTALLDIR)
.PHONY: clean
clean:
for file in $(CLEANEXTS); do rm -f *.$$file; done
# Generate dependencies of .ccp files on .hpp files
include $(subst .cpp,.d,$(SOURCES))
%.d: %.cpp
$(CC) -M $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
Running this file I obtained the following error:
/usr/bin/ld: fastpd.o: relocation R_X86_64_32 against `.rodata' can
not be used when making a shared object; recompile with -fPIC
fastpd.o: error adding symbols: Bad value
Checking the terminal output, I observed that the following commands were executed:
g++ -c -o fastpd.o fastpd.cpp
g++ -c -o graph.o graph.cpp
g++ -c -o LinkedBlockList.o LinkedBlockList.cpp
g++ -c -o maxflow.o maxflow.cpp
No -fPIC!
My question is: Which lines of the Makefile execute these commands and how to add -fPIC to them?
Any references to good ressources to understand the entire Makefile above would be very much appreciated as well!
Thank you very much in advance for your help!
Which lines of the Makefile execute these commands... ?
The short answer is none. The rule...
$(OUTPUTFILE): $(subst .cpp,.o,$(SOURCES))
$(CXX) -shared -fPIC $(LDFLAGS) -o $# $^
only specifies the link time dependencies and command. The -fPIC option needs to be specified when you compile the source file but you haven't provided any rule to build a .o from a .cpp so make falls back on its implicit rule which (for the purposes of this example) is essentially...
%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
So the obvious solution is to add -fPIC to CXXFLAGS...
CXXFLAGS += -fPIC

GCC linking a static library

I have seen questions like these on SO but everyone has different answers and directory structures that aren't working for me.
My makefile:
CC = g++
DEBUG = -g -std=c++11
TARGET = main
OBJECT_FILES = BingResultSet.o main.o
INC_PATH = -I HTTPClientLib/include
LIB_PATH = -L HTTPClientLib/lib/
start: clean BingResultSet.o main.o
$(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)
rm -f *.o
BingResultSet.o: BingResultSet.cpp BingResultSet.h
$(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) -c BingResultSet.cpp
main.o: main.cpp
$(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) -c main.cpp
clean:
rm -f $(OBJECT_FILES) $(TARGET)
My file structure:
/Desktop/DataMiner/.cpp, .h, and makefile
/Desktop/DataMiner/HTTPClientLib/include/HTTPClient.h
/Desktop/DataMiner/HTTPClientLib/lib/HTTPClient.a
What's the correct way to link my static lib in my makefile?
Here's my $0.02:
there was no static library involved. Assuming you meant the .o files
you mix dependencies and build rules, instead, avoid repeating build rules:
$(TARGET): $(OBJECT_FILES)
$(CXX) $(DEBUG) $(INC_PATH) $^ -o $# $(LIB_PATH)
%.o: %.cpp
$(CXX) $(DEBUG) $(INC_PATH) -c $< -o $#
You used CC for a C++ compiler. That's strange. Use CXX
You used LDFLAGS when you were just compiling
You hardcoded the source and destination paths. Instead use the automatic variables ($^, $< for source; $# for destination)
You tried to hardcode header dependencies. That's error-prone and messes up source specification (you don't want $^ to list .h files in your command line...). Instead, use gcc -MM¹ to generate the dependencies for you!
Next, do a conditional include of those dependencies:
.depends:
$(CXX) -MM $(CXXFLAGS) -c *.cpp > $#
-include .depends
It's usually handy to keep the .o files so you can speed up builds. Of course, this was not a good plan until you generated the header dependencies automatically. If you insist, you can comment the .PRECIOUS target. Intermediate targets are automatically deleted by GNU Make
Here's the integrated offering I ended up with:
CXX = g++
TARGET = main
OBJECT_FILES = BingResultSet.o main.o
INC_PATH = -I HTTPClientLib/include
LIB_PATH = -L HTTPClientLib/lib/
CPPFLAGS = -g -std=c++11
CPPFLAGS+= $(INC_PATH)
# standard derived flags:
CXXFLAGS+=$(CPPFLAGS)
LDFLAGS+=$(LIB_PATH)
start: .depends $(TARGET)
$(TARGET): $(OBJECT_FILES)
$(CXX) $(CXXFLAGS) $^ -o $# $(LDFLAGS)
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
clean:
rm -f .depends $(OBJECT_FILES) $(TARGET)
# to keep the .o files:
.PRECIOUS: $(OBJECT_FILES)
.depends:
$(CXX) -MM $(CXXFLAGS) -c *.cpp > $#
-include .depends
On a very simple sample set of files you get:
$ make clean
rm -f .depends BingResultSet.o main.o main
$ make
g++ -MM -g -std=c++11 -I HTTPClientLib/include -c *.cpp > .depends
g++ -I HTTPClientLib/include -c BingResultSet.cpp -o BingResultSet.o
g++ -I HTTPClientLib/include -c main.cpp -o main.o
g++ -I HTTPClientLib/include BingResultSet.o main.o -o main -L HTTPClientLib/lib/
$ cat .depends
BingResultSet.o: BingResultSet.cpp BingResultSet.h
main.o: main.cpp BingResultSet.h
test.o: test.cpp
¹ (or similar, see man-page)

make error as: unrecognized option '-mcpu=arm1176jzf-s'

I am trying to compile some C to run on a friendlyARM for days now without any luck, i think im close but getting this error:
kevin#kevin-VirtualBox:~/Desktop/makef$ make
arm-none-linux-gnueabi-gcc -c -o obj/main.o main.c -I./
as: unrecognized option '-mcpu=arm1176jzf-s'
make: *** [obj/main.o] Error 1
Does anyone know how to what this error means and how to fix it?
steps i have tried:
1
touch *.*
make clean
make
(error as: unrecognized option '-mcpu=arm1176jzf-s)
2
touch *.*
make clean
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-l
(error as: unrecognized option '-mcpu=arm1176jzf-s)
the Makefile :
IDIR =./
CC=arm-none-linux-gnueabi-gcc
CFLAGS=-I$(IDIR)
ODIR=obj
LDIR =./
LIBS=-lgd -lrt
_DEPS = main.h Makefile
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = main.o serial.o fb.o menu_main.o timer.o cmdin.o buzzer.o statemachine.o inout.o network.o text_file_input.o text_file_input_oven.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
main: $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
It means the version of gcc that you have installed does not understand the option -mcpu=arm1176jzf-s
Either you have an older version of gcc which does not accept that option, or you have a version of gcc that has cross compiling support turned off.

Linker input file unused c++ g++ make file

I am unable to figure out what is causing this error that I keep getting upon making my project:
i686-apple-darwin11-llvm-g++-4.2: -lncurses: linker input file unused because linking not done
And my make file looks like this:
CC = g++
LIB_FLAGS = -l ncurses
FLAGS = $(LIB_FLAGS)
DEPENDENCIES = window.o element.o
# FINAL OUTPUTS
main: main.cpp $(DEPENDENCIES)
$(CC) $(FLAGS) -o main.out main.cpp $(DEPENDENCIES)
# MODULES
window.o: main.h classes/window.cpp
$(CC) $(FLAGS) -c classes/window.cpp
element.o: main.h classes/element.cpp
$(CC) $(FLAGS) -c classes/element.cpp
# CLEAN
clean:
rm -rf *.o
rm main.out
Everything compiles okay, but I'm just curious what is causing this error message and what it means..
You are passing linker options to a compiler invocation together with -c, which means that linking is not performed and thereby -l options are unused. In your case, your LIB_FLAGS should not be in FLAGS, but instead specified in the the main: ... rule:
main: main.cpp
$(CC) $(FLAGS) $(LIB_FLAGS) ...
Do not give link flags when you compile (-c flag) your source files. Take a look for this example makefile (very similar as in makefile docs)
CPP = g++
CPPFLAGS =-Wall -g
OBJECTS = main.o net.o
PREFIX = /usr/local
.SUFFIXES: .cpp .o
.cpp.o:
$(CPP) $(CPPFLAGS) -c $<
.o:
$(CPP) $(CPPFLAGS) $^ -o $#
main: $(OBJECTS)
main.o: main.cpp
net.o: net.cpp net.h
.PHONY:
install: main
mkdir -p $(PREFIX)/bin
rm -f $(PREFIX)/bin/main
cp main $(PREFIX)/bin/main
clean:
rm -f *.o main
As has been mentioned already you're passing linker-related flags at the compile stage. Usually you want different flags for compiling and linking, e.g.
CC = g++
CPPFLAGS = -Wall -g -c -o $#
LDFLAGS = -l ncurses -o $#
DEPENDENCIES = main.o window.o element.o
# FINAL OUTPUTS
main: $(DEPENDENCIES)
$(CC) $(LDFLAGS) $(DEPENDENCIES)
# MODULES
main.o: main.h main.cpp
$(CC) $(CPPFLAGS) main.cpp
window.o: main.h classes/window.cpp
$(CC) $(CPPFLAGS) classes/window.cpp
element.o: main.h classes/element.cpp
$(CC) $(CPPFLAGS) classes/element.cpp
# CLEAN
clean:
-rm main $(DEPENDENCIES)