Using make for my program - c++

I have a bunch of files in different folders:
/ai/client.cpp # contains the main function
/ai/utils/geometry.h
/ai/utils/geometry.cpp
/ai/world/world.h
/ai/world/world.cpp
/ai/world/ball.h
/ai/world/ball.cpp
/ai/world/bat.h
/ai/world/bat.cpp
How do I write a makefile to compile this program? I'm using Ubuntu.

Make is a versatile tool, and there are many different subtleties to using it. However, you can keep things simple:
OBJ := ai/utils/geometry.o ai/world/world.o ai/world/ball.o ai/world/bat.o
all: ai/client
.PHONY: all # specific to GNU make, which is what Ubuntu provides
ai/client: ai/client.o $OBJ
# this rule means each .cpp file depends on its corresponding header
# and, since the .o files depend on .cpp files (a builtin make rule),
# they will be recompiled if the headers change
#
# you can also get more complex and generate dependencies automatically
# look at the -MM option for gcc, for example
%.cpp: %.h

you should check out that you have installed g++ and build-essential
here is some insight into the makefile black magic consorsium
I think that make1 is directory aware so typing mydirectory/myfile.cpp should work well
the rest is basic g++ commands but the tutorial on 1 should be enough :)
1 the program that executes makefiles

its working thank you every1 for your valuable comments
specially for the links
on the previous post i forgot to write the client.cpp file on line 6
but my mistake was that i had included one header with a mistake in the client.cpp and it could never find it.

First result in google: http://www.opussoftware.com/tutorial/TutMakefile.htm
Seems to be a pretty good tutorial. Should be pretty simple to understand, note that they talk about the GNU version of make, which is what is most commonly used. There is also the BSD version though if you use a BSD-based OS(such as OpenBSD, NetBSD, or FreeBSD.. anyone know about Mac OSX?)

Related

How To Get g++ to list paths to all #included files

I would like to have g++/gcc tell me the paths to everything non-system it is #include-ing in C++ build. Turns out, that is a tough search as Google mus-interprets it about ten different ways.
I want these filenames and paths so I can add them to the search path for Exuberant CTAGS. We have a huge project and if I use ctags on the whole thing it takes about half an hour to generate the tags file and nearly as long for the editor to do a look-up.
We use CMakeLisats to do the compiling. If there is a directive I can paste into the CMakeLists.txt, that would be extra wonderfulness.
I don't really need the default paths and filenames, Johnathan Wakely gave a good tool for that here. I think that pretty much covers the fact that this is a cross compile job. I don't need the cross-system files either.
Try gcc or g++ with the -H option (to the preprocessor part of it). From the doc:
-H
Print the name of each header file used, in addition to other normal activities. Each name is indented to show how deep in the ‘#include’ stack it is. Precompiled header files are also printed, even if they are found to be invalid; an invalid precompiled header file is printed with ‘...x’ and a valid one with ‘...!’ .
It tells you all the headers which are included. You may filter out (with grep -v or awk) those that you don't want.
You could also consider developing your GCC plugin to register these headers somewhere (e.g. in your sqlite database), perhaps inspired by this draft report, or the CHARIOT or DECODER European projects. You could also consider using, or extending, the Clang static analyzer.
In contrast to the -M options suggested in Oliver Matthews' answer, it does not tell you more (but gives all the included files).
You need to invoke g++ with the -M option.
From the manual:
Instead of outputting the result of preprocessing, output a rule
suitable for make describing the dependencies of the main source file.
The preprocessor outputs one make rule containing the object file name
for that source file, a colon, and the names of all the included
files, including those coming from -include or -imacros command line
options.
It's worth reading the manual to consider the other -M sub options (-MM and -MF in particular may be of use).

How do I compile multi-file C++ programs in all subdirectories?

I have a bunch of C++ programs each in its own sub-directory. Each sub-directory has a single C++ program in several files -- a .h and a .cpp file for each class plus a main .cpp program. I want to compile each program placing the executable in the corresponding sub-directory. (I also want to run each program and redirect its output to a file that is placed in the corresponding sub-directory but if I can get the compilation to work, I shouldn't have a problem figuring out this part.)
I'm using the bash shell on a UNIX system (actually the UNIX emulator Cygwin that runs on top of Windows).
I've managed to find on the web, a short scrip for compiling one-file programs in the current directory but that's as far as I've gotten. That script is as follows.
for f in *.cpp;
do g++ -Wall -O2 "$f" -o "{f/.cpp/}";
done;
I would really appreciate it someone could help me out. I need to do this task on average once every two weeks (more like 8 weeks in a row, then not for 8 weeks, etc.)
Unless you're masochistic, use makefiles instead of shell scripts.
Since (apparently) each executable depends on all the .h and .cpp files in the same directory, the makefiles will be easy to write -- each will have something like:
whatever.exe: x.obj y.obj z.obj
g++ -o whatever.exe x.obj y.obj z.obj
You can also add a target in each to run the resulting executable:
run:
whatever.exe
With that you'll use make run to run the executable.
Then you'll (probably) want a makefile in the root directory that recursively makes the target in each subdirectory, then runs each (as described above).
This has a couple of good points -- primarily that it's actually built for this kind of task, so it actually does it well. Another is that it takes note of the timestamps on the files, so it only rebuilds the executables that actually need it (i.e., where at least one of the files that executable depends on has been modified since the executable itself was built).
Assuming you have a directory all of whose immediate subdirectories are all c++ programs, then use some variation on this...
for D in */; do cd "$D";
# then either call make or call your g++
# with whatever arguments in here
# or nest that script you found online if it seems to
# be doing the trick for you.
cd ../;
done;
That will move in to each directory, do its thing (whatever you want that to be) and then move back out.

Makefile for Linux from Xcode-written C++ program

I've written a simple c++ program on Xcode, all contained within ONE FILE called huffmanGenerator.cpp. The program reads input from a file on the user's computer, and writes output to a file saved to their computer.
The instructor has asked us to create a makefile so that our programs compile and run with g++ OR gcc in Linux; however she never showed us how to do so, and when the class asked for help, her answer was we could figure it out.
I found many links online, but they're all very confusing as this is all new to me, and most of them fail to answer even the most basic questions like what kind of file should the makefile be? Is it a .txt? Should I just save one in word?
Please help do what the instructor won't, enlighten me. Thanks!
what kind of file should the makefile be?
It should be a plaintext file called Makefile or makefile. The reason the name matters is because when you run the make command, it looks for a file with this name by default for directions on how to compile your code. You can also name it whatever you want as long as you specify the name when you run it (make -f filename).
Is it a .txt?
No, it has no extension. Extensions don't mean that much in *nix.
Should I just save one in word? (Assume you mean Microsoft Word.)
No, definitely not. Whitespace (tabs/spaces/new lines) have meaning in these files, so you should use an editor that won't add formatting to the file. Something like pico/vi/etc.
Here is an example of a makefile, that I think does what you are asking.
# You can change your compiler to gcc / g++ here.
CC=g++
# Add whatever flags you want to use here.
CFLAGS=-c -Wall
all:
$(CC) $(CFLAGS) huffmanGenerator.cpp -o huffmanGenerator
#Use something like this to run `make clean` which deletes your object files, so you can do a fresh compile.
#clean:
# rm -rf *o huffmanGenerator
As a side note, you would be served well not to blame your professor for not spelling out everything for you. When you graduate, you will often be given tasks that have no other directions than a set of requirements and a deadline. You will need to figure it out. You could have easily made this make file by visiting http://mrbook.org/tutorials/make/ (search google for 'makefile tutorial').
The makefile should be called Makefile. It is just a text file.
You need a text editor. There are many to choose from, vim, emacs, nano, pico, ..., etc.
Open a command line and run, say
$ pico Makefile
Then you would enter the contents of the Makefile
all:
g++ -o huffmanGenerator huffmanGenerator.cpp
Save and exit and run make
$ make

CXXSources-- what are they?

I'm new to compiling C/C++ with the aid of make. I downloaded an open source project and noticed that there is in the make file CXXSources and CXXObjects. I think I understand roughly what the make file is doing with them but...
I don't have any of the source files listed under CXXSources. Are these like dependences I'm supposed to know how to find? Is there any custom as to what CXXSource is versus just Source?
Added link to project: http://www.fim.uni-passau.de/en/fim/faculty/chairs/theoretische-informatik/projects.html
More specifically, the GML parser, eg. http://www.fim.uni-passau.de/fileadmin/files/lehrstuhl/brandenburg/projekte/gml/gml-parser.tar.gz
It seems to be getting stuck on the line:
gml_to_graph : $(CXXOBJECTS) gml_scanner.o gml_parser.o
$(CXX) -o gml_to_graph_demo $(CXXOBJECTS) gml_parser.o gml_scanner.o -L$(LEDADIR)/lib -lG -lL -lm
The $CXXObjects is defined by
CXXSOURCES = gml_to_graph.cc gml_to_graph_demo.cc
CXXOBJECTS = $(CXXSOURCES:.cc=.o)
So I need gml_to_graph.cc, it seems. Or maybe I'm wrong?
Usually, the variables are set before the point where you see them. This could be
(a) via the environment
(b) before including the quoted makefile
(c) in the quoted makefile, but preceding the location quoted
To see (verbosely) what GNU make takes into account, do:
make -Bn
(it will show everything that _would get executed)
Even more verbose:
make -p all
It will show you all the internal variable expansions.
If you post a link or more information, we will be able to come up with less generic (and hence possibly less confusing) answers

Help with rake dependency mapping

I'm writing a Rakefile for a C++ project. I want it to identify #includes automatically, forcing the rebuilding of object files that depend on changed source files. I have a working solution, but I think it can be better. I'm looking for suggestions for:
Suggestions for improving my function
Libraries, gems, or tools that do the work for me
Links to cool C++ Rakefiles that I should check out that do similar things
Here's what I have so far. It's a function that returns the list of dependencies given a source file. I feed in the source file for a given object file, and I want a list of files that will force me to rebuild my object file.
def find_deps( file )
deps = Array.new
# Find all include statements
cmd = "grep -r -h -E \"#include\" #{file}"
includes = `#{cmd}`
includes.each do |line|
dep = line[ /\.\/(\w+\/)*\w+\.(cpp|h|hpp)/ ]
unless dep.nil?
deps << dep # Add the dependency to the list
deps += find_deps( dep )
end
end
return deps
end
I should note that all of my includes look like this right now:
#include "./Path/From/Top/Level/To/My/File.h" // For top-level files like main.cpp
#include "../../../Path/From/Top/To/My/File.h" // Otherwise
Note that I'm using double quotes for includes within my project and angle brackets for external library includes. I'm open to suggestions on alternative ways to do my include pathing that make my life easier.
Use the gcc command to generate a Make dependency list instead, and parse that:
g++ -M -MM -MF - inputfile.cpp
See man gcc or info gcc for details.
I'm sure there are different schools of thought with respect to what to put in #include directives. I advise against putting the whole path in your #includes. Instead, set up the proper include paths in your compile command (with -I). This makes it easier to relocate files in the future and more readable (in my opinion). It may sound minor, but the ability to reorganize as a project evolves is definitely valuable.
Using the preprocessor (see #greyfade) to generate the dependency list has the advantage that it will expand the header paths for you based on your include dirs.
Update: see also the Importing Dependencies section of the Rakefile doc for a library that reads the makefile dependency format.