Makefile with Bison and Lex - c++

I am doing a simple Interpreter using bison and lex. This is my make file content.
#
# makefile for ccalc
#
OBJS += mylang.o SM.o lex.o parse.o
# rules
%.c: %.y
bison -o $(#:%.o=%.d) $<
%.c: %.l
flex -o$(#:%.o=%.d) -i $<
# dependencies
mylang: mylang.yy.tab.c lex.c $(OBJS)
#echo g++ -Os -std=c++0x -omylang $(OBJS)
#g++ -Os -std=c++0x -omylang $(OBJS)
#echo ' '
# source
mylang.o: mylang.cpp
SM.o: SM.cpp SM.h
lex.o: lex.c
parse.o: mylang.yy.tab.c
mylang.yy.tab.c: mylang.yy
lex.c: mylang.ll
When run this make file, The command running as
g++ -c -o SM.o SM.cpp
But I want to run as,
g++ -Os -std=c++0x -c -o SM.o SM.cpp
What Should I change in my make file to run with c++0x Compiler Version.

Set CXXFLAGS flags accordingly:
CXXFLAGS="-Os -std=c++0"
make uses internal defaults rule to compile
c++ files to .o files. You can display them with make -p.
The rules in your case are
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
COMPILE.cpp = $(COMPILE.cc)
%.o: %.cpp
# recipe to execute (built-in):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<

Related

Makefile how to specify the include directory

I am trying to write a make file for the following program
MY file/folder structure is as follows
Folder/File structure
./demo/utilities.c
./demo/utilities.h
./demo/makefile
./include/GeographicLib/UTMUPS.h
./include/GeographicLib/Constant.h
./include/GeographicLib/xxxxxxx
in the file utilities.h
#include <GeographicLib/UTMUPS.h>
in the file UTMUPS.h
#include <GeographicLib/Constant.h>
in the makefile
# preprocessor
PREPROC_FLAGS += -DEIGEN_DONT_ALIGN_STATICALLY
INC_XTRA_DIR = ../include
CC=g++
CPPFLAGS= $(PREPROC_FLAGS)
CFLAGS=-O2 -g -Wall -W -I$(INC_XTRA_DIR)
CXXFLAGS=-O2 -g -Wall -W -fpic -std=c++11
# short hand
OBJDIR=obj
Utilities_h = utilities.h GeographicLib/UTMUPS.hpp
utilities.o: utilities.c $(Utilities_h)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
all: $(FINAL_TARGET)
$(FINAL_TARGET): $(OBJ)
$(CC) -g -o $# $^ $(LDFLAGS)
ifneq ($(wildcard ../databases/.),)
cp $# ../
endif
TargetList = $(FINAL_TARGET)
clean:
rm -f $(TargetList) *.o *~
echo Clean done.
The question I want to ask is
When I compile the following project, it say it can't find "#include 'GeographicLib/UTMUPS.h'". in the utilities.h. what should the naming be in this case. My thought is that by adding -I$(INC_XTRA_DIR), or ../include ... it should search for GeographicLib/UTMUPS.h
what about the file that UTMUPS.h is dependent on(in this case Constant.h), what should be the addressing
Edit: I run make at the root directory... maybe that's the reason for the error.
THanks

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

Make recompiles non modified files

I have a makefile for my program but I got everything recompiled every time I run it, even if I modify nothing.
Every time I run make it recompiles simHwIntf.cpp showHelp.cpp and sendFromFile.cpp
This is my make file:
IDIR = inc
LDIR = -L/usr/lib/x86_64-linux-gnu/
SDIR = src
ODIR = obj
BINDIR = bin
LDLIBS = -luhd
OBJ = $(patsubst %,$(ODIR)/%,$(O_FILES))
CC = g++
CFLAGS = -Wall -std=c++11 -I $(IDIR) #-Werror
BINARIES= main
C_FILES = simHwIntf.cpp showHelp.cpp sendFromFile.cpp
H_FILES = simHwIntf.h
O_FILES = $(C_FILES:.cpp=.o)
all: $(BINARIES)
#echo "Make file executed"
$(BINARIES): $(O_FILES)
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(OBJ) $(LDIR) $(LDLIBS)
fileCreator: fileCreator.o
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(ODIR)/fileCreator.o
fileHandler: fileHandler.o
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(ODIR)/fileHandler.o
backYard: backYard.o
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(ODIR)/backYard.o
%.o: $(SDIR)/%.cpp $(IDIR)/$(H_FILES)
$(CC) $(CFLAGS) -c -o $(ODIR)/$# $<
clean:
-rm -rf $(ODIR)/*.o *~
distclean: clean
-rm -rf $(BINDIR)/*
Each time the output in the shell is:
g++ -Wall -std=c++11 -I inc -c -o obj/simHwIntf.o src/simHwIntf.cpp
g++ -Wall -std=c++11 -I inc -c -o obj/showHelp.o src/showHelp.cpp
g++ -Wall -std=c++11 -I inc -c -o obj/sendFromFile.o src/sendFromFile.cpp
g++ -Wall -std=c++11 -I inc -o bin/main obj/simHwIntf.o obj/showHelp.o obj/sendFromFile.o -L/usr/lib/x86_64-linux-gnu/ -luhd
Make file executed
I've already search and read this: (How do I make Makefile to recompile only changed files?) but didn't help much.
Anybody that could give me a hand with this ?
I have a doubt with the directories, maybe one or several directories are re-created each time I run make and this causes everything inside to look like new to the compiler.
Thanks
You can see what triggered the build by echoing the dependencies that changed. Add this to your %.o target :
#echo [triggered by changes in $?]
You should also use the VPATH special variable instead of specifying the sources path in your %.o target. See GNU make VPATH documentation
Please try replacing
%.o: $(SDIR)/%.cpp $(IDIR)/$(H_FILES)
$(CC) $(CFLAGS) -c -o $(ODIR)/$# $<
with
$(ODIR)/%.o: $(SDIR)/%.cpp $(IDIR)/$(H_FILES)
$(CC) $(CFLAGS) -c -o $(ODIR)/$# $<
Directories matter when you define targets.
If a define a rule
myexec: objdir/myexec.o
$(CC) $(CFLAGS) -o bindir/myexec objdir/myexec.o $(LDFLAGS)
Make believes that that this would create the file myexec in the working directory. When you rerun make the target myexec wasn't found, so it will be created again. Add the paths in the targets and it should work.
Try replacing
BINARIES= main
with
BINARIES= $(BINDIR)/main
and the rule
$(CC) $(CFLAGS) -o $(BINDIR)/$# $(OBJ) $(LDIR) $(LDLIBS)
with
$(CC) $(CFLAGS) -o $# $^ $(LDIR) $(LDLIBS)
And change the other rules similarly.
Note, in general it is a bad idea to use $# in combination with a path when creating the target in some rule (as in $(BINDIR)/$#), because this will never create the actual target file. A bare $# should be sufficient.

C++ File Requires Library Support

I'm trying to compile a simple program from the terminal that utilizes the condition_variable class. Upon building, I get the following 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.
In researching this error here, I added the necessary flag to my make file, but I'm still getting the same error.
Here is my makefile:
CXX= g++ $(CCFLAGS)
MAIN= main.o
DATACLASS= dataclass.o
OBJS = $(MAIN) $(DATACLASS)
LIBS= -pthread
CCFLAGS= -g -std=c++11
all: main
main: $(MAIN) $(DATACLASS)
$(CXX) -o main $(MAIN) $(DATACLASS) $(LIBS)
dataclass: $(DATACLASS)
$(CXX) -o dataclass $(DATACLASS) $(LIBS)
clean:
rm -f $(OBJS) $(OBJS:.o=.d)
realclean:
rm -f $(OBJS) $(OBJS:.o=.d) main
%.d: %.cc
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $# : /g'\'' > $#; \
[ -s $# ] || rm -f $#'
include $(OBJS:.o=.d)
I'm sure I'm missing something small and stupid as I'm new to makefiles, but any help would be greatly appreciated.
Rewrite CXX to CXX = g++
Change CCFLAGS to CXXFLAGS = -g -std=c++11, and
Rewrite your rules to $(CXX) $(CXXFLAGS) ....
$(CXX) $(CXXFLAGS) will then be replaced with g++ -g -std=c++11. This is more of a standard method for defining a makefile. Here is a snippet of the resulting makefile.
CXX = g++
MAIN = main.o
DATACLASS = dataclass.o
OBJS = $(MAIN) $(DATACLASS)
LIBS = -pthread
CXXFLAGS = -g -std=c++11
all: main
main: $(OBJS)
$(CXX) $(CXXFLAGS) $? -o $# $(LIBS)
As a side note, are you sure this rule should be defined as such?
dataclass: $(DATACLASS)
$(CXX) $(CXXFLAGS) $? -o $# $(LIBS)
Should the target not be dataclass.o or $(DATACLASS) and the prerequisite some other file?
Note: I've also included some make automatic variables to tidy up the makefile rules.
$? - is replaced by all prerequisites
$# - is replaced by the target name

How to expand makefile variable in prerequisites list?

I am having an issue defining a prerequisites for my targets while using file lists in variables the problem is as follows:
in my makefile:
... some basic defines
SOURCES=HelloC.cpp \
HelloS.cpp \
HelloI.cpp \
main.cpp
SOURCES_CLIENT=Hello_Client_impl.cpp \
HelloC.cpp
OBJECTS_SERVER_DIR=obj_s/
OBJECTS_CLIENT_DIR=obj_c/
OBJECTS_SERVER=$(addprefix $(OBJECTS_SERVER_DIR),$(SOURCES:.cpp=.o))
OBJECTS_CLIENT=$(addprefix $(OBJECTS_CLIENT_DIR),$(SOURCES_CLIENT:.cpp=.o))
EXECUTABLE_SERVER=server
EXECUTABLE_CLIENT=client
all: dirs server_exe client_exe
dirs:
#echo create dirs
$(CREATE_DIR) $(OBJECTS_SERVER_DIR)
$(CREATE_DIR) $(OBJECTS_CLIENT_DIR)
server_exe: $(EXECUTABLE_SERVER)
client_exe: $(EXECUTABLE_CLIENT)
$(EXECUTABLE_SERVER): $(OBJECTS_SERVER)
$(CXX) $^ $(LFLAGS) $(LIBS) -o $#
$(EXECUTABLE_CLIENT): $(OBJECTS_CLIENT)
$(CXX) $^ $(LFLAGS) $(LIBS) -o $#
# problematic line 1
$(OBJECTS_SERVER): $(SOURCES)
$(CXX) -c $(CPPFLAGS) -o $# $<
# problematic line 2
$(OBJECTS_CLIENT): %.o : %.cpp
$(CXX) -c $(CPPFLAGS) -o $# $<
Running it (as dry run) I will get:
$ make -n
echo create dirs
mkdir -p obj_s/
mkdir -p obj_c/
g++ -c -Wall -I. -I/usr/include/ -I/usr/include/orbsvcs/ -I/usr/include/tao/ -I/usr/include/tao/PortableServer/ -o obj_s/HelloC.o HelloC.cpp
g++ -c -Wall -I. -I/usr/include/ -I/usr/include/orbsvcs/ -I/usr/include/tao/ -I/usr/include/tao/PortableServer/ -o obj_s/HelloS.o HelloC.cpp
g++ -c -Wall -I. -I/usr/include/ -I/usr/include/orbsvcs/ -I/usr/include/tao/ -I/usr/include/tao/PortableServer/ -o obj_s/HelloI.o HelloC.cpp
g++ -c -Wall -I. -I/usr/include/ -I/usr/include/orbsvcs/ -I/usr/include/tao/ -I/usr/include/tao/PortableServer/ -o obj_s/main.o HelloC.cpp
g++ obj_s/HelloC.o obj_s/HelloS.o obj_s/HelloI.o obj_s/main.o -L/usr/lib64/ -lTAO_PortableServer -lTAO_AnyTypeCode -lTAO -lACE -o server
make: *** No rule to make target `obj_c/Hello_Client_impl.cpp', needed by `obj_c/Hello_Client_impl.o'. Stop.
problematic line 1 will not expand and will always keep the first source file (HelloC.cpp) as a parameter while the second one is defined with prefix. How can I handle this so that it compiles? I would like to have source files in root dir and object files in obj_c and obj_s directories
EDIT: I originally answered the wrong question in haste, sorry about that. Anyway, the static pattern rule is the way to go, but you have to factor in the prefix. Instead of
$(OBJECTS_CLIENT): %.o : %.cpp
Use
$(OBJECTS_CLIENT): $(OBJECTS_CLIENT_DIR)%.o : %.cpp