Im trying to compile a C++ project using MinGW and can compile a simple main.cpp file with hello world without problems using g++ main.cpp -o main and also with external libraries using main.cpp extlib.cpp -o main.
But say im working on a rather large project with 10s of .cpp files organised inside of different files, how can I get the compiler to find all the cpp files that are needed? I know i can use main.cpp libs/*.cpp -o main but this will only compile all the source files inside of libs but not inside folders in libs.
Ive looked into make and cmake but dont understand how those automate the process if you still have to manually enter the directories. Is there no way to simply hit compile or at least a command line command to compile all the needed files inside a directory? This seems to work with #include without issues?
If you want to stick with MinGW and GNU Make I would probably use a Makefile that looks something like this to start with. You basically only need to maintain the srcs-variable by adding your source-files there. Usually you can use the wildcard-function for this if you have sub dirs. The rest of the Makefile (which can be left alone) sets up a build of an executable main.exe that depends on all the object-files. I also included dependency-handling via the deps-variable and the compiler flag -MMD which comes in handy when the project grows.
srcs := $(wildcard *.cpp) $(wildcard dir1/*.cpp) $(wildcard dir2/*.cpp)
objs := $(srcs:.cpp=.o)
deps := $(objs:.o=.d)
app := main.exe
CXXFLAGS := -MMD -Og -g -Wall -Werror -Wpedantic -std=c++2a
$(app): $(objs)
$(CXX) $(LDFLAGS) -o $# $^ $(LDLIBS)
-include $(deps)
.PHONY: clean
clean:
rm -f $(objs) $(deps)
I use CMake for simple projects.
Here's the simplest example I came with (CMakeLists.txt to put along your main.cpp in the root of your project):
cmake_minimum_required(VERSION 3.1)
SET(CMAKE_APP_NAME "Project")
project (${CMAKE_APP_NAME})
# list here your directories
INCLUDE_DIRECTORIES(dir1)
INCLUDE_DIRECTORIES(dir2)
# add an executable and list all files to compile
add_executable(${CMAKE_APP_NAME} main.cpp
dir1/file1.cpp
dir1/file1.h
dir2/file2.h
dir2/file2.cpp
)
Once your project becomes more complex, you could use file(GLOB*) to avoid writing all the files.
Overall, the most "automated" way to build a larger project is to use CMake. Keep learning it. You can use file(GLOB) to avoid listing every file in CMakeLists.txt. This is not recommended (see discussion here), but I do it anyway and never had any issues.
Related
I am new to C++ and am trying to get the hang of build systems like make/CMake. Coming from Go, it seems that there is a constant risk that if you forget to do a little thing, your binaries will become stale. In particular, I can't find a best practice for remembering to keep dependencies/prerequisites updated in make/CMake. I'm hoping I am missing something obvious.
For example, suppose I have a basic makefile that just compiles main.cpp:
CFLAGS = -stdlib=libc++ -std=c++17
main: main.o
clang++ $(CFLAGS) main.o -o main
main.o: main.cpp
clang++ $(CFLAGS) -c main.cpp -o main.o
main.cpp:
#include <iostream>
int main() {
std::cout << "Hello, world\n";
}
So far so good; make works as expected. But suppose I have some other header-only library called cow.cpp:
#include <iostream>
namespace cow {
void moo() {
std::cout << "Moo!\n";
}
}
And I decide to call moo() from within main.cpp via `include "cow.cpp":
#include <iostream>
#include "cow.cpp"
int main() {
std::cout << "Hello, world\n";
cow::moo();
}
However, I forget to update the dependencies for main.o in makefile. This mistake is not revealed during the obvious testing period of running make and rerunning the binary ./main, because the whole cow.cpp library is directly included in main.cpp. So everything seems fine, and Moo! is printed out as expected.
But when I change cow.cpp to print Bark! instead of Moo!, then running make doesn't do anything and now my ./main binary is out of date, and Moo! is still printed from ./main.
I'm very curious to hear how experienced C++ devs avoid this problem with much more complicated codebases. Perhaps if you force yourself to split every file into a header and an implementation file, you'll at least be able to quickly correct all such errors? This doesn't seem bulletproof either; since header files sometimes contain some inline implementations.
My example uses make instead of CMake, but it looks like CMake has the same dependency listing problem in target_link_libraries (though transitivity helps a bit).
As a related question: it seems like the obvious solution is for the build system to just look at the source files and infer dependencies (it can just go one level in and rely on CMake to handle transitivity). Is there a reason this doesn't work? Is there a build system that actually does this, or should I write my own?
Thanks!
First of all you will need to reference the dependencies file in your Makefile.
This can be done with the function
SOURCES := $(wildcard *.cpp)
DEPENDS := $(patsubst %.cpp,%.d,$(SOURCES))
wich will take the name of all *.cpp files and substitute and append the extension *.d to name your dependency.
Then in your code
-include $(DEPENDS)
- tells the Makefile to not complain if the files do not exist. If they exist they will be included and recompile your sources properly according to the dependencies.
Finally the dependencies can be created automatically with the options: -MMD -MP for the rules to create the objects file. Here you can find a complete explanation. What generates the dependencies is MMD; MP is to avoid some errors. If you want to recompile when system libraries are updated use MD instead of MMD.
In your case you can try:
main.o: main.cpp
clang++ $(CFLAGS) -MMD -MP -c main.cpp -o main.o
If you have more files it is better to have a single rule to create object files. Something like:
%.o: %.cpp Makefile
clang++ $(CFLAGS) -MMD -MP -c $< -o $#
You can take a look also at this 2 great answers:
one
two
In your case a more suitable Makefile should look like the following (there might be some errors but let me know):
CXX = clang++
CXXFLAGS = -stdlib=libc++ -std=c++17
WARNING := -Wall -Wextra
PROJDIR := .
SOURCEDIR := $(PROJDIR)/
SOURCES := $(wildcard $(SOURCEDIR)/*.cpp)
OBJDIR := $(PROJDIR)/
OBJECTS := $(patsubst $(SOURCEDIR)/%.cpp,$(OBJDIR)/%.o,$(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.cpp,$(OBJDIR)/%.d,$(SOURCES))
# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean
all: main
clean:
$(RM) $(OBJECTS) $(DEPENDS) main
# Linking the executable from the object files
main: $(OBJECTS)
$(CXX) $(WARNING) $(CXXFLAGS) $^ -o $#
#include your dependencies
-include $(DEPENDS)
#create OBJDIR if not existin (you should not need this)
$(OBJDIR):
mkdir -p $(OBJDIR)
$(OBJDIR)/%.o: $(SOURCEDIR)/%.cpp Makefile | $(OBJDIR)
$(CXX) $(WARNING) $(CXXFLAGS) -MMD -MP -c $< -o $#
EDIT to answer comments
As another question, is there any problem with rewriting the DEPENDS definition as just DEPENDS := $(wildcard $(OBJDIR)/*.d)?
Nice question, it took me a while to see your point
From here
$(wildcard pattern…) This string, used anywhere in a makefile, is
replaced by a space-separated list of names of existing files that
match one of the given file name patterns. If no existing file name
matches a pattern, then that pattern is omitted from the output of the
wildcard function.
So wildcard return a list of the file names matching the pattern. patsubst acts on strings, it does not care about what are those strings: it is used as a way to create the file names of the dependencies, not the files themselves. In the Makefile example that I posted DEPENDS is actually use in two cases: when cleaning with make clean and with include so in this case they both work because you are not using DEPENDS in any rule. There are some differences (I tried to run and you should too to confirm). With DEPENDS := $(patsubst $(SOURCEDIR)/%.cpp,$(OBJDIR)/%.d,$(SOURCES)) if you run make clean dependencies *.d that do not have a correspondent *.cpp file will not be removed while they will with your change. On the contrary you might include dependencies not relevant to your *.cpp file.
I asked this questions: let's see the answers.
If the .d files get deleted from carelessness but the .o files remain, then we are in trouble. In the original example, if main.d is deleted and then cow.cpp is subsequently changed, make won't realize it needs to recompile main.o and thus it will never recreate the dependency file. Is there a way to cheaply create the .d files without recompiling the object files? If so then we could probably recreate all the /.d files on every make command?
Nice question again.
Yes, you are right. Actually it was an error of mine. This happens because of the rule
main: main.o
$(CXX) $(WARNING) $(CFLAGS) main.o -o main
actually should have been:
main: $(OBJECTS)
$(CXX) $(WARNING) $(CXXFLAGS) $^ -o $#
so that it got relinked (the executable is updated) whenever one of the objects change and they will change whenever one their cpp file change.
One problem remains: if you delete your dependencies but not the objects, and change only one or more header files (but not the sources) then your program is not updated.
I corrected also the previous part of the answer.
EDIT 2
To create the dependencies you can also add a new rule to your Makefile:
here is an example.
I'm playing around some tutorial code from this OpenCV 2 Cookbook. The code doesn't come with any Makefiles, and I'd like to create a Makefile that can Make all of the files in the codebase. My plan is to compile all the files with profiling, and then make a script that runs all the executables and collects the gprof results. Then, I can get some intuition for the computation time of various OpenCV functions.
The codebase is arranged like this: tutorial_code/Chapter[1-10]/*.cpp
Each .cpp file is self-sufficient and can be compiled without linking against other modules in this codebase. (There are a few small header-only libraries, though.)
Here are a couple things that I'm stuck up on:
Typically, the $(EXEC) in a Makefile represents a file that is the culmination of much of the building effort. However, in my case, I want to create a separate $(EXEC) for each .cpp file. I think I'm close to getting this right, but so far my Makefile just generates *.o but not *.out
I understand that SOURCES = $(wildcard *.cpp) is a way to "collect" the set of cpp files in the current directory. It would make sense that SOURCES = $(wildcard */*.cpp) would drill down and grab all .cpp files in the subdirectories. It doesn't seem to work, though.
Starting from this tutorial, I set up a Makefile that implements the proposed functionality. It doesn't quite work... $(wildcard */*.cpp) doesn't seem to drill down into directories, and I'm not sure how to do something like $< and $# to refer to basefilename.o and to create basefilename.out.
CC = g++
CC_FLAGS = -w `pkg-config opencv --cflags`
LINK = g++
LINKOPTS = -pg `pkg-config opencv --libs`
SOURCES = $(wildcard */*.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
EXEC = $(SOURCES:.cpp=.out)
%.out: %.o
$(LINK) $< $(LINKOPTS) -o $#
%.o: %.cpp
$(CC) -c $(CC_FLAGS) $< -o $#
clean:
rm -f $(EXEC) $(OBJECTS)
I'm fairly familiar with Makefiles and OpenCV, and I haven't had a problem compiling my own projects by hand-coding the lists of dependencies, objects, etc in Makefiles. However, for the matter at hand, it'd be fantastic to just automatically make everything without much user intervention.
Feel free to comment, email, or message me for a copy of the codebase that I'm trying to compile.
I've also thought of making a script that iterates through the tutorial_code/Chapter[1-10] directories and creates one Makefile for each directory. Then, I'd make an other function in the script to call Make once in each directory. The idea of doing one grand Makefile sounds like more fun, though.
EDIT: This does work if I use SOURCES = $(wildcard *.cpp) and place the Makefile in the same directory where cpp files are located. However, I'm still trying to figure out how to have $(wildcard */*.cpp) drill down into subdirectories.
EDIT 2: The Makefile shown above now works properly. To see the earlier version, feel free to scroll through the edit history.
You can write a version of wildcard that works recursively to any depth using only make functions:
find-recursive = \
$(wildcard $1/$2) \
$(foreach f,$(wildcard $1/*/.),\
$(call find-recursive,$(patsubst %/.,%,$f),$2))
SOURCES = $(call find-recursive,.,*.cpp)
I have made a project in Xcode who implements an algorithm in just 1 c++ file. To compile it needs an library who is in a directory called libgambit in an other directory. The directory structure looks like this:
lib/
libgambit/libgambit.cc
libgambit.h
game.cc
game.h
...
src/Game\ Theoretic\ Analysis/convertion.cc
convertion.h
Makefile
So what I need is a makefile who first builds everything whats in libgambit and uses the object files who result from that to build and link convertion.cc. The executable should then be in the same folder as the makefile.
It seems a pretty easy question but I'm suffering on it for 2 days now.
There's more than one way to do it. Here is a crude but effective way:
LIBSRCS := $(wildcard $(PATHTOLIB)/lib/libgambit/*.cc)
LIBOBJS := $(LIBSRCS:.cc=.o)
convertion: convertion.o $(LIBOBJS)
#g++ -Wall $^ -o $#
%.o: %.cc
#g++ -Wall -Ilib/libgambit -c $< -o $#
This does not track dependencies very well (if you alter a header file, Make won't notice that some objects must be rebuilt), but it is good enough for now. Let us know if you want to try advanced dependency handling.
You can use the Makefile developed here. It allows you to add new files and directories to the build without changing the Makefile.
Does anyone know of a tool that generates a makefile by scanning a directory for source files?
It may be naive:
no need to detect external dependencies
use default compiler/linker settings
You can write a Makefile that does this for you:
SOURCES=$(shell find . -name "*.cpp")
OBJECTS=$(SOURCES:%.cpp=%.o)
TARGET=foo
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
.PHONY: clean
clean:
rm -f $(TARGET) $(OBJECTS)
Just place this in root directory of your source hierarchy and run make (you'll need GNU Make for this to work).
(Note that I'm not fluent in Makefileish so maybe this can be done easier.)
CMake does it and it even creates makefiles and Visual Studio projects. http://www.cmake.org/
All you need to do is creating a CMakeLists.txt file containing the follwing lines:
file(GLOB sources *.h *.c *.cxx *.cpp *.hxx)
add_executable(Foo ${sources})
Then go into a clean directory and type:
cmake /path/to/project/
That will create makefiles on that clean build directory.
This is what I would use for a simple project:
CC = $(CXX)
CXXFLAGS += -ansi -pedantic -W -Wall -Werror
CPPFLAGS += -I<Dir Where Boost Lives>
SOURCES = $(wildcard *.cpp)
OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES))
all: myApp
myApp: $(OBJECTS)
The only restriction is that if you are building an executable called myApp. Then one of the source files should be named myApp.cpp (which is where I put main).
There's a very old script called 'makedepend' that used to make very simple makefiles. I've since switched over to cmake for almost everything.
Here's the wiki article http://en.wikipedia.org/wiki/Makedepend, note the list of Alternatives at the bottom including depcomp in automake, and the -M flag in gcc.
EDIT: As someone pointed out to me in another question, gcc -MM *.cpp > Makefile produces a rather nice simple makefile. You only have to prepend your CPPFLAGS and a rule for constructing the entire binary... which will take the form:
CPPFLAGS=-Wall
LDFLAGS=-lm
all: binary_name
binary_name: foo.o bar.o baz.o biff.o
no need to detect external dependencies
use default compiler/linker settings
Why script then? Provided that all your project source files are *.cpp and in current directory:
all: $(notdir $(CURDIR))
$(notdir $(CURDIR)): $(subst .cpp,.o,$(wildcard *.cpp))
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
The Makefile would build the all the source files with default compiler/linker settings into an executable named after the name of the current directory.
Otherwise, I generally recommend people to try SCons instead of make where it is much simpler and intuitive. Added bonus that there is no need to code manually clean targets, source/header dependency checking is built-in, it is natively recursive and supports properly libraries.
As described in the linked discussion, HWUT is a tool that
can generate pretty Makefiles, searching for dependencies and include files in directories that you tell it. On windows you need to install MinGW and Ctags. Under Linux gcc and ctags are most likely present. It is OpenSource and free to use.
Especially, when generating Unit Tests for some already existing modules of some larger project with bad cohesion, this feautures easily spares you hours or even days.
I've looking to find a simple recommended "minimal" c++ makefile for linux which will use g++ to compile and link a single file and h file. Ideally the make file will not even have the physical file names in it and only have a .cpp to .o transform. What is the best way to generate such a makefile without diving into the horrors of autoconf?
The current dir contains, for example
t.cpp
t.h
and I want a makefile for that to be created. I tried autoconf but its assuming .h is gcc instead of g++. Yes, while not a beginner, I am relearning from years ago best approaches to project manipulation and hence am looking for automated ways to create and maintain makefiles for small projects.
If it is a single file, you can type
make t
And it will invoke
g++ t.cpp -o t
This doesn't even require a Makefile in the directory, although it will get confused if you have a t.cpp and a t.c and a t.java, etc etc.
Also a real Makefile:
SOURCES := t.cpp
# Objs are all the sources, with .cpp replaced by .o
OBJS := $(SOURCES:.cpp=.o)
all: t
# Compile the binary 't' by calling the compiler with cflags, lflags, and any libs (if defined) and the list of objects.
t: $(OBJS)
$(CC) $(CFLAGS) -o t $(OBJS) $(LFLAGS) $(LIBS)
# Get a .o from a .cpp by calling compiler with cflags and includes (if defined)
.cpp.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $<
Here is a generic makefile from my code snippets directory:
SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
DEPS=$(SOURCES:.cpp=.d)
BINS=$(SOURCES:.cpp=)
CFLAGS+=-MMD
CXXFLAGS+=-MMD
all: $(BINS)
.PHONY: clean
clean:
$(RM) $(OBJECTS) $(DEPS) $(BINS)
-include $(DEPS)
As long as you have one .cpp source producing one binary, you don't need anything more. I have only used it with GNU make, and the dependency generation uses gcc syntax (also supported by icc). If you are using the SUN compilers, you need to change "-MMD" to "-xMMD". Also, ensure that the tab on the start of the line after clean: does not get changed to spaces when you paste this code or make will give you a missing separator error.
Have you looked at SCons?
Simply create a SConstruct file with the following:
Program("t.cpp")
Then type:
scons
Done!
Assuming no preconfigured system-wide make settings:
CXX = g++
CPPFLAGS = # put pre-processor settings (-I, -D, etc) here
CXXFLAGS = -Wall # put compiler settings here
LDFLAGS = # put linker settings here
test: test.o
$(CXX) -o $# $(CXXFLAGS) $(LDFLAGS) test.o
.cpp.o:
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
test.cpp: test.h
a fairly small GNU Makefile, using predefined rules and auto-deps:
CC=c++
CXXFLAGS=-g -Wall -Wextra -MMD
LDLIBS=-lm
program: program.o sub.o
clean:
$(RM) *.o *.d program
-include $(wildcard *.d)
Have you looked at OMake ?
OMakeroot
open build/C
DefineCommandVars()
.SUBDIRS: .
OMakefile
.DEFAULT: $(CXXProgram test, test)
Then on Linux or Windows, simply type:
omake
As a bonus, you automatically get:
parallel builds with the -j option (same as make).
MD5 checksums instead of timestamps (build becomes resilient to time synchronization failures).
Automatic and accurate C/C++ header dependencies.
Accurate inter-directory dependencies (something that recursive make does not offer).
Portability (1 build chain to rule them all, immune to path style issues).
A real programming language (better than GNU make).
Some good references on creating a basic Makefile
http://en.wikipedia.org/wiki/Make_(software)
http://mrbook.org/tutorials/make/
http://www.opussoftware.com/tutorial/TutMakefile.htm
http://www.hsrl.rutgers.edu/ug/make_help.html
The first couple in particular have minimal example Makefiles like you were describing. Hope that helps.
SConstruct with debug option:
env = Environment()
if ARGUMENTS.get('debug', 0):
env.Append(CCFLAGS = ' -g')
env.Program( source = "template.cpp" )
florin has a good starting point. I didn't like gnu autoconf so I started there and took the concept further and called it the MagicMakefile. I have 3 versions of it from simple to more complex. The latest is now on github: https://github.com/jdkoftinoff/magicmake
Basically, it assumes you have a standard layout for the source files of your project and uses the wildcard function to create the makefile rules on the fly which are then eval'd, handling header file dependancies, cross compiling, unit tests, install, and packaging.
[edit] At this point I use cmake for all my projects since it generates useful project files for many build systems.
jeff koftinoff
I was hunting around for what a minimal Makefile might look like other than
some_stuff:
#echo "Hello World"
I know I am late for this party, but I thought I would toss my hat into the ring as well. The following is my one directory project Makefile I have used for years. With a little modification it scales to use multiple directories (e.g. src, obj, bin, header, test, etc). Assumes all headers and source files are in the current directory. And, have to give the project a name which is used for the output binary name.
NAME = my_project
FILES = $(shell basename -a $$(ls *.cpp) | sed 's/\.cpp//g')
SRC = $(patsubst %, %.cpp, $(FILES))
OBJ = $(patsubst %, %.o, $(FILES))
HDR = $(patsubst %, -include %.h, $(FILES))
CXX = g++ -Wall
%.o : %.cpp
$(CXX) $(HDR) -c -o $# $<
build: $(OBJ)
$(CXX) -o $(NAME) $(OBJ)
clean:
rm -vf $(NAME) $(OBJ)
If your issues are because autoconf thinks the .h file is a c file, try renaming it to .hpp or .h++