C++, Pass a command line argument to makefile - c++

I need to pass a command line argument which is a file name as a string to the program(main.cpp) in the makefile. I have seen most of the other post but don't understand how to implement them into my file. How should I proceed to do that? Thank you!
main.cpp
Program structure
makefile
OBJS = main.o HashTable.o Book.o
SOURCE = main.cpp HashTable.cpp Book.cpp
HEADER = HashTable.h Book.h
OUT = book
CC = g++
FLAGS = -g -c -Wall -Wextra -std=c++1z
all: $(OBJS)
$(CC) -g $(OBJS) -o $(OUT) $(LFLAGS)
main.o: main.cpp
$(CC) $(FLAGS) main.cpp
HashTable.o: HashTable.cpp
$(CC) $(FLAGS) HashTable.cpp
Book.o: Book.cpp
$(CC) $(FLAGS) Book.cpp
clean:
rm -f $(OBJS) $(OUT)

Related

Im working on a makefile which should build a library and then also include that library when building the entire program

INC_DIR = ./include
SRC_DIR = ./src
OBJ_DIR = ./obj
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp))
H_FILES = $(wildcard $(INC_DIR)/*.cpp)
OBJ_FILES=$(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/%.o,$(SRC_FILES)
TARGET = PT3
CC = g++
CFLAGS = - fPIC -c -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
CPPFLAGS = $(addprefix -I, $(INC_DIR))
clean:
rm -f $(OBJECTS) $(TARGET)
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# $^
%.o: %.cc
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# -c $<
g++ -shared -fPIC -o libtest.so $(OBJECTS)
main.o: main.cc
$(CC) $(CFLAGS) $(CPPFLAGS) -L/pt3/lib -o maintest main.cc -libtest
this is currently what I have and i know its not syntactically right or remotely working but Im getting stuck on creating the shared library so I dont even know what else wouldnt compile.**
INC_DIR = ./include
SRC_DIR = ./src
SRC_FILES = $(sort $(shell find $(SRC_DIR) -name '*.cc'))
OBJ_FILES = $(SRC_FILES:.cc=.o)
TARGET = PT3
CC = g++
CFLAGS = -fPIC -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
CPPFLAGS = $(addprefix -I, $(INC_DIR))
#clean:
# rm -f $(OBJECTS) $(TARGET)
all: $(TARGET)
$(TARGET): $(OBJ_FILES)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# $^
%.o: %.cc
$(CC) $(CFLAGS) $(CPPFLAGS) -o $# -c $<
libtest.so: $(OBJ_FILES)
$(CC) -shared -fPIC -o $# $^
maintest: main.o libtest.so
$(CC) $(CFLAGS) $(CPPFLAGS) -L. -o maintest main.o -libtest
this is what i rewrote the code to however Im getting a no input files error, but Im not sure if thats coming from a wrong read / failure to get into the required folders, or due to possibly missing a -o or -c?
Ive worked on the code some more following the suggestions and have come to this:
CXX = g++
CXXFLAGS := -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp)
OBJECTS=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
INC_DIR = include
SRC_DIR = src
OBJ_DIR = obj
TEST_DIR = tests
LIB_DIR = lib
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -fPIC -Iinclude -o $# -c $<
clean:
rm -f $(OBJECTS) $(TEST_DIR)/main.o
$(LIB_DIR)/libtest.so: $(OBJECTS)
#echo frank
$(CXX) -shared -fPIC -o $# $^
$(TEST_DIR)/main.o: $(TEST_DIR)/main.cc
$(CXX) $(CXXFLAGS) -Iinclude -o $# -c $<
maintest: $(TEST_DIR)/main.o $(LIB_DIR)/libtest.so
$(CXX) $(CXXFLAGS) -Llib -Iinclude -o $# $< -ltest
everything seems to compile fine however when running the maintest program it returns an error saying: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
thanks for the suggestions so far I feel like Im on the verge of actually getting the makefile working as intended
You've already written the recipe for the library (which builds it in the working directory -- we can change that later if you want):
g++ -shared -fPIC -o libtest.so $(OBJECTS)
The next step is to put it into a rule:
libtest.so: $(OBJECTS)
g++ -shared -fPIC -o libtest.so $(OBJECTS)
Then clean it up:
libtest.so: $(OBJECTS)
g++ -shared -fPIC -o $# $^
It looks as if you want the executable to be maintest, so let's write a rule for that:
maintest: main.o libtest.so
$(CC) $(CFLAGS) $(CPPFLAGS) -L. -o maintest main.o -ltest
Give that a try. We can make further adjustments once that much works.
EDIT: I see that there are a few other problems in your makefile. Your variables won't work as written. Do you name your source files "foo.cc" or "foo.cpp"?
EDIT: I can see that we'll have to do this in stages.
Step 1. Try this:
CXX = g++
CXXFLAGS := -Wall -Werror -pedantic -std=c++11 -Wno-c++11-extensions
INC_DIR = include
SRC_DIR = src
OBJ_DIR = obj
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -Iinclude -o $# -c $<
Try to build one or two object files with this, as in make obj/foo.o.
Step 2. Add a rule for main.o, and test it:
$(OBJ_DIR)/main.o: main.cc
$(CXX) $(CXXFLAGS) -Iinclude -o $# -c $<
Step 3. Add a "do nothing" rule for the library, and verify that it builds all of the objects:
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp)
OBJECTS=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
libtest.so: $(OBJECTS)
#echo doing nothing
Step 4. Change the library rule to actually build the library:
libtest.so: $(OBJECTS)
$(CXX) -shared -fPIC -o $# $^
Step 5. Add a rule to build the test:
maintest: main.o libtest.so
$(CXX) $(CXXFLAGS) -L. -o $# $< -ltest

GNU make does not build headers correctly if changed

I have this makefile:
CC=g++
CFLAGS=-c -Wall
all: hello
hello: main.o client.o
$(CC) main.o client.o -o hello
client.o: client.cpp client.h
$(CC) $(CFLAGS) client.cpp -o client.o
main.o: main.cpp
$(CC) $(CFLAGS) main.cpp -o main.o
clean:
rm -rf *o hello
Whenever I make changes in hello.h, client.o is rebuilt when I execute make. But when I try the resulting executable ./hello the change does not seem to happen.
The change is only reflected on ./hello if I add client.h to the main.o: rule like that
main.o: main.cpp client.h
$(CC) $(CFLAGS) main.cpp -o main.o
This will make things very difficult to maintain my code, any idea how to solve this problem?
Edit:
tried this change:
main.o: main.cpp
$(CC) $(CFLAGS) -MD main.cpp -o main.o
but did not help.
UPDATE (final version):
TARGET = hello
CC = g++
CPPFLAGS = -Wall -MP -MD
LINKER = g++ -o
LFLAGS = -Wall
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SOURCES := $(wildcard $(SRCDIR)/*.cpp)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
DEPS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.d)
RM = rm -rf
DIR_GUARD = mkdir -p $(#D)
$(BINDIR)/$(TARGET): $(OBJECTS)
#$(DIR_GUARD)
#$(LINKER) $# $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o: $(SRCDIR)/%.cpp
#$(DIR_GUARD)
#$(CC) $(CPPFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
-include $(DEPS)
.PHONEY: clean
clean:
#$(RM) $(OBJDIR)/* $(BINDIR)/*
#echo "Cleanup complete!"
Thanks guys for all the help, you are truly amazing.
The problem is that the dependency of main.o on client.h is not specified in your Makefile. Use:
main.o: main.cpp client.h
$(CC) $(CFLAGS) main.cpp -o main.o

MakeFile : Header in different Directory - Error

I am trying to avoid relative paths in header declaration of C++ files. So, I had used the makefile by following an online example. But I am getting error. Please check the code and help me to resolve this
COMPILER = g++
IDIR = ./include
CXXFLAGS += -I$(IDIR)
CFLAGS += -I$(IDIR)
EXEC = hello
OBJECTS = main.o factorial.o hello.o
all: $(EXEC)
(---- I had also used CFLAGS instead of CXXFLAGS below but the same result###)
$(EXEC): $(OBJECTS)
$(COMPILER) $(CXXFLAGS) $(OBJECTS) -o $(EXEC)
main.o: main.cpp ./include/functions.h
$(COMPILER) $(CXXFLAGS) -c main.cpp
factorial.o: main.cpp ./include/functions.h
$(COMPILER) $(CXXFLAGS) -c factorial.cpp
hello.o: main.cpp ./include/functions.h
$(COMPILER) $(CXXFLAGS) -c hello.cpp
Error:
make: * No rule to make target 'include / functions.h "
required by "main.o" to create. Closing.
Directory Structure is
- main.cpp
- factorial.cpp
- hello.cpp
- MakeFile.mk
- +include (dir)
----->functions.h
main.cpp contains ----include "functions.h"---- in the header declaration
You are not using h files as a source files.
there should only be:
main.o: main.cpp
$(COMPILER) $(CXXFLAGS) -c main.cpp
edited:
I copy your folder content and write simple application where hello.cpp have a simple void function, factorial.cpp have simple int-returning function ane main.cpp have int main() and uses this functions, include.h hafe declarations of these two dummy functions.
Now. My makefile looks:
COMPILER = g++
IDIR = ./include
CXXFLAGS += -I$(IDIR)
EXEC = hello
OBJECTS = main.o factorial.o hello.o
all: $(EXEC)
$(EXEC): $(OBJECTS)
$(COMPILER) $(CXXFLAGS) $(OBJECTS) -o $(EXEC)
main.o: main.cpp factorial.o hello.o
$(COMPILER) -c $(CXXFLAGS) $^ -o $#
factorial.o: factorial.cpp
$(COMPILER) -c $(CXXFLAGS) $^ -o $#
hello.o: hello.cpp
$(COMPILER) -c $(CXXFLAGS) $^ -o $#
download for my sample
That should help You!
This is a pure make error message. The error is not related to the content of any .cpp or .h file. The error actually can come only from the content of the Makefile, and of the presence or absence of the files named in it.
As per this error message, make states that it cannot find the file include/functions.h. Double check it actually is here, with correct name and matching case.
For debugging purpose you can add the following lines to your Makefile:
./include/functions.h:
touch $#
It will instruct make to create an empty include/functions.h file if it's missing.

Having issues with a Makefile for a c++ project written in Xcode

I wrote this c++ project in Xcode, and now I have to create a Makefile so that it compiles properly. Here is the Makefile:
CC = g++
CFLAGS =
PROG = TrainStation
MAIN = main.cpp
OBJS = ArrivalEvent.o DepartureEvent.o Event.o EventCoordinator.o InSwitchEvent.o ListItem.o OrderedList.o OutSwitchEvent.o PriorityQueue.o Train.o
# compiling rules
# WARNING: *must* have a tab before each definition
$(PROG): $(OBJS) main.o # The error was leaving out main.o from this line
$(CC) $(CFLAGS) $(OBJS) main.o -o $(PROG)
ArrivalEvent.o: ArrivalEvent.cpp ArrivalEvent.h EventCoordinator.h InSwitchEvent.h Event.h EventCoordinator.h Train.h
$(CC) $(CFLAGS) -c ArrivalEvent.cpp -o ArrivalEvent.o
DepartureEvent.o: DepartureEvent.cpp DepartureEvent.h OutSwitchEvent.h Event.h EventCoordinator.h Train.h
$(CC) $(CFLAGS) -c DepartureEvent.cpp -o DepartureEvent.o
Event.o: Event.cpp Event.h EventCoordinator.h ListItem.h
$(CC) $(CFLAGS) -c Event.cpp -o Event.o
EventCoordinator.o: EventCoordinator.cpp EventCoordinator.h OrderedList.h Event.h Train.h PriorityQueue.h ArrivalEvent.h InSwitchEvent.h
$(CC) $(CFLAGS) -c EventCoordinator.cpp -o EventCoordinator.o
InSwitchEvent.o: InSwitchEvent.cpp InSwitchEvent.h DepartureEvent.h Event.h EventCoordinator.h Train.h
$(CC) $(CFLAGS) -c InSwitchEvent.cpp -o InSwitchEvent.o
ListItem.o: ListItem.cpp ListItem.h
$(CC) $(CFLAGS) -c ListItem.cpp -o ListItem.o
OrderedList.o: OrderedList.cpp OrderedList.h ListItem.h
$(CC) $(CFLAGS) -c OrderedList.cpp -o OrderedList.o
OutSwitchEvent.o: OutSwitchEvent.cpp OutSwitchEvent.h Train.h InSwitchEvent.h Event.h EventCoordinator.h
$(CC) $(CFLAGS) -c OutSwitchEvent.cpp -o OutSwitchEvent.o
PriorityQueue.o: PriorityQueue.cpp PriorityQueue.h OrderedList.h
$(CC) $(CFLAGS) -c PriorityQueue.cpp -o PriorityQueue.o
Train.o: Train.cpp Train.h ListItem.h
$(CC) $(CFLAGS) -c Train.cpp -o Train.o
main.o: $(MAIN) Train.h OrderedList.h PriorityQueue.h EventCoordinator.h
$(CC) $(CFLAGS) -c $(MAIN) -o main.o
clean:
rm -f $(PROG) $(OBJS)
I have written Makefiles before, but never one with so many files to coordinate, and it seems that it is skipping the rule for main.o [EDIT: I updated my Makefile but now receive this different error]
$ make
g++ -c ArrivalEvent.cpp -o ArrivalEvent.o
g++ -c DepartureEvent.cpp -o DepartureEvent.o
g++ -c Event.cpp -o Event.o
g++ -c EventCoordinator.cpp -o EventCoordinator.o
g++ -c InSwitchEvent.cpp -o InSwitchEvent.o
g++ -c ListItem.cpp -o ListItem.o
g++ -c OrderedList.cpp -o OrderedList.o
g++ -c OutSwitchEvent.cpp -o OutSwitchEvent.o
g++ -c PriorityQueue.cpp -o PriorityQueue.o
g++ -c Train.cpp -o Train.o
g++ main.o ArrivalEvent.o DepartureEvent.o Event.o EventCoordinator.o InSwitchEvent.o ListItem.o OrderedList.o OutSwitchEvent.o PriorityQueue.o Train.o -o TrainStation
i686-apple-darwin11-llvm-g++-4.2: main.o: No such file or directory
make: *** [TrainStation] Error 1
I know this is an error with g++, and that it probably has to do with me leaving out a file somewhere or not linking it, but I can't seem to figure out what is going wrong. Perhaps someone with fresh eyes may be able to spot the problem?
EDIT: PROBLEM SOLVED
My problem was that $(OBJS) doesn't contain main.o, so the rule for $(PROG) doesn't depend on main.o at all. Once I added main.o to the rule for $(PROG), then the rule for main.o is executed correctly.
After MAIN = main.cpp you do never use this variable to compile and link the main.cpp file.
Change this:
$(CC) $(CFLAGS) $(OBJS) -o $(PROG)
to this:
$(CC) $(CFLAGS) $(OBJS) main.o -o $(PROG)

make with .cpp and .c?

My Makefile keeps telling me
make: *** No rule to make target `rs232.c',
I list the files here (rs232.c is at the very end) -
SOURCES_RAW=codeprofiler.cpp gametimer.cpp timer.cpp timeprofile.cpp vector4.cpp matrix.cpp agent.cpp agentcontroller.cpp dummy.cpp evader.cpp pursuer.cpp goal.cpp player.cpp graphdata.cpp graph.cpp cubiccoefs.cpp segment.cpp trajectory.cpp anode.cpp arrayvector4.cpp color.cpp drawcomponent.cpp drawcontroller.cpp flags.cpp global.cpp map_analyzer.cpp minheap.cpp node.cpp quadtree.cpp queue.cpp results.cpp sensor.cpp settings.cpp utility.cpp world.cpp gui.cpp main.cpp logger.cpp parameters.cpp counter.cpp polygon.cpp line.cpp robot_driver_agent.cpp position.cpp robot_driver_priorityqueue.cpp main.cpp robot_driver_tree.cpp robot_driver_grid.cpp path.cpp tcpserver.cpp tcpclient.cpp servercontrol.cpp clientcontrol.cpp Robot.cpp udpserver.cpp udpclient.cpp rs232.c
All of there files are in a folder called src. So I do -
SRCDIR= src
SOURCES:=$(SOURCES_RAW)
SOURCES:=$(patsubst %.c, $(SRCDIR)/%.c, $(SOURCES))
SOURCES:=$(patsubst %.cpp, $(SRCDIR)/%.cpp, $(SOURCES))
Why will it not compile the .c file?
The entire Makefile is -
INCLUDE = -I/usr/X11R6/include
#INCLUDE_W32 = -Isrc
CC=g++
CFLAGS=-w -D LINUX -fpermissive
CFLAGS_R= -w -D LINUX -O3 -fpermissive
CFLAGS_D=-w -D LINUX -fpermissive
OBJ= obj
OBJ_DEBUG= obj_debug
OBJDIR= release
SRCDIR= src
LDFLAGS= -L/usr/X11R6/lib$(LIBSELECT) -lGL -lfltk -lfltk_gl -lXext -lX11 -lglut -lGLU -lfltk_images
SOURCES_RAW=codeprofiler.cpp gametimer.cpp timer.cpp timeprofile.cpp vector4.cpp matrix.cpp agent.cpp agentcontroller.cpp dummy.cpp evader.cpp pursuer.cpp goal.cpp player.cpp graphdata.cpp graph.cpp cubiccoefs.cpp segment.cpp trajectory.cpp anode.cpp arrayvector4.cpp color.cpp drawcomponent.cpp drawcontroller.cpp flags.cpp global.cpp map_analyzer.cpp minheap.cpp node.cpp quadtree.cpp queue.cpp results.cpp sensor.cpp settings.cpp utility.cpp world.cpp gui.cpp main.cpp logger.cpp parameters.cpp counter.cpp polygon.cpp line.cpp robot_driver_agent.cpp position.cpp robot_driver_priorityqueue.cpp main.cpp robot_driver_tree.cpp robot_driver_grid.cpp path.cpp tcpserver.cpp tcpclient.cpp servercontrol.cpp clientcontrol.cpp Robot.cpp udpserver.cpp udpclient.cpp rs232.c
TARGET:= pursuit_evasion
TARGETD:= pursuit_evasion_d
TARGETP:= pursuit_evasion_p
TARGETW32:= pursuit_evasion_w32
OBJECTS:=$(SOURCES_RAW:.cpp=.o)
OBJECTS:=$(patsubst %.o,$(OBJDIR)/%.o, $(OBJECTS))
SOURCES:=$(SOURCES_RAW)
SOURCES:=$(patsubst %.cpp, $(SRCDIR)/%.cpp, $(SOURCES))
OBJ_DEBUG:=$(SOURCES_RAW:.cpp=.o)
OBJ_DEBUG:=$(patsubst %.o,debug/%.o, $(OBJ_DEBUG))
OBJECTS_P:=$(SOURCES_RAW:.cpp=.o)
OBJECTS_P:=$(patsubst %.o,profile/%.o, $(OBJECTS_P))
OBJDIR=obj
all: $(TARGET)
#--- Release
$(TARGET): $(OBJECTS)
$(CC) -w -D LINUX $(INCLUDE) $^ -o $# $(LDFLAGS)
release/%.o: src/%.cpp
$(CC) -c $< $(CFLAGS_R) -o $#
#--- Debug
debug: $(TARGETD)
$(TARGETD): $(OBJ_DEBUG)
$(CC) -w -D LINUX $(INCLUDE) $^ -o $# $(LDFLAGS)
debug/%.o: src/%.cpp
$(CC) -c -g $< $(CFLAGS)-o $#
#-- Profile
profile: $(TARGETP)
$(TARGETP): $(OBJECTS_P)
$(CC) -w -g -pg -D LINUX $(INCLUDE) $^ -o $# $(LDFLAGS)
profile/%.o: src/%.cpp
$(CC) -c -g -pg $< $(CFLAGS)-o $#
win32: $(TARGETW32)
$(TARGETW32): $(OBJECTS)
$(CC) -w -D WIN32 $(INCLUDE_W32) $^ -o $# $(LDFLAGS)
.PHONY : clean
clean:
rm -f release/*.o
rm -f debug/*.o
rm -f profile/*.o
rm -f $(TARGET) $(TARGETD) $(TARGETP)
All your previous files (before rs232.c) are actually C++ files.
I guess you have a rule to compile C++ files, later in your makefile, but do you also have a rule to compile pure C files?
Like:
%.o: %.c
gcc [...]
EDIT - Just for you to know
You're not forced to specify all the files you want to compile.
Take a look at the foreach and dir functions.
With that, you can get all files matching a specific pattern from a directory.
Example:
FILES = $(foreach dir,$(DIR_SRC),$(wildcard $(DIR_SRC)*.cpp))