Portably Compile Entire Directory - c++

Is there a clean/portable way to descend recursively from a given directory, compiling all found .cpp files into a single output file? I'm not sure if makefiles are capable of this sort of thing, or if it's a job for some kind of build script, but I'd like to avoid maintaining various IDEs' project files along with my code.

There are different things that you can do here. I would suggest that you use a multiplatform build system, and follow the documentation for it. I have used CMake in the past, but I wouldn't know how to tell it to compile all files in a directory.
The advantage is that the user can use CMake to generate project files for most common IDEs, so it would allow VisualStudio users to generate VS solutions, MacOSX users to generate Xcode projects, Eclipse CDK projects in pretty much any environment, Makefiles...

There's the wildcard function which can be used to match a pattern like so:
CXX_FILES = $(wildcard src/*.cpp) # All .cpp files in the directory
This is not recursive, but will at least save you from having to manually specify the files in a certain directory. The rule for building them would look something like this:
CXX_FILES = $(wildcard src/*.cpp) # All .cpp files in the directory
OBJ_FILES = $(CXX_FILES:src/%.cpp=$(OBJ_DIR)/%.o) # Corresponding .o files
# Rules
all: $(OBJ_FILES)
g++ $(OBJ_FILES) -o output_filename
$(OBJ_DIR)/%.o: src/%.cpp
g++ -c $< -o $#
Oh, and to answer your question, this method is completely portable.

Related

How to recompile source file every time while using cmake 2.8.2 in single build for c++11 and c++98 for shared library creation?

I have a project directory structure of:
Root
Source
Common
MyFolder
++ My 3 source files and header
When I am building my project it generates 3 to 4 shared libraries. Lib1 compiled using c++98 and others using c++11. Flags are added in CmakeList.txt which is at root.
I need my 3 source files to be compiled for Lib1 and for other Libs as as well. but here what happens is compiler is first compiling my source file for lib using c++11 and then it is trying to use same .o file for Lib1 as well. So for .o file which is generated using c++11 is throwing exception when same is used for c++98 compiled library.
So how do write this in CmakeList.txt such that compiler rather than trying to use same .o file will compile source file again for Lib1(c++98 compiled library)
Is there any flag I can specify so that it won't take precompiled .o file and will compile it again ?
Here flags are not being overridden for different shared libraries but actually same object file by make file is being used for different flags
This is sort of counter to how makefiles and cmake usually work.
Most users consider it really important that make performs an incremental build.
The usual way with makefiles is to do make clean which is supposed to remove any binaries and object files that were created.
However, sometimes I write cmake scripts that use globbing over the source directory to assemble the project. (That means, it says "just grab all *.cpp files in the /src folder and make an executable from them".) A makefile cannot check what files in a directory, so the make build will be broken after I add a new file, and make clean won't fix it -- the whole makefile will need to be regenerated by cmake.
Usually what I do is, I write a simple bash script, named rebuild.sh or something,
#!/bin/bash
rm -rf build
mkdir build
cd build
cmake ..
make -j3
./tests
And I put that in the root of my repository, and add /build to my .gitignore. I call that when I want to do a full rebuild -- it nukes the build directory, so its foolproof. When I want an incremental rebuild, I just type make again in the /build directory.
The rebuild.sh script can also serve a double purpose if you use travis-ci for continuous integration.
Most build system assume the compiled objects remain the same within the same pass. To avoid shooting your foot I would suggest telling the build system they were actually different objects, while still compiled from same source files.
I'm not familiar with cmake but this is how you do with make:
For example you have a a.cpp which you want to compile 2 times for different compiler options:
#include <stdio.h>
int main(int argc, char* argv[]) {
printf ("Hello %d\n", TOKEN);
return 0;
}
And the Makefile would looks like:
SRC := $(wildcard *.cpp)
OBJ_1 := $(patsubst %.cpp,%_1.o,$(SRC))
OBJ_2 := $(patsubst %.cpp,%_2.o,$(SRC))
all: pass1 pass2
pass1: $(OBJ_1)
gcc -o $# $(OBJ_1) -lstdc++
pass2: $(OBJ_2)
gcc -o $# $(OBJ_2) -lstdc++
%_1.o: %.cpp
gcc -DTOKEN=1 -c $< -o $#
%_2.o: %.cpp
gcc -DTOKEN=2 -c $< -o $#
clean:
rm -f $(OBJ_1) $(OBJ_2)
What I do here is generate two different list of object from the same source files, which you can even do the same for dependency(-MMD -MP flags).

Structuring Makefiles with multiple directories

I am trying to compile my project which has the following structure
Project:
MakeFile
Executable
Source1
.cxx
.h
Source2
.cxx
.h
Build
*.o
And I'm having difficulty writting a Makefile to compile. I currently have commands like:
Src1 = $(wildcard $(SRCDIR1)/*.cxx)
Obj1 = $(patsubst $(SRCDIR1)/%.cxx, $(OBJDIR)/%.o, $(Src1))
But then I have difficulty making the compile rules for the object files a) Because I can no longer do:
$(Obj1): %.cxx
$(CXX) $(CFLAGS) -c $(#:.o=.cxx) -o $#
Because the '$#' command now includes the path of the build directory and b) because the prerequisites now include the build path and I should have a source path. I have read large bits of the make manual to try and find a solution but no luck.
Any help towards a solution appreciated!
Jack
From personal experience, after playing around a bit with "raw" Makefiles, I'd really recommend using some tool building the Makefiles for you, like automake or cmake.
You'll still have to specify all the source files manually - but at least I prefer that to manually fiddling around with the Makefiles.
One option I prefer is building an isomorphic directory structure in the build directory. That is, a source file ${src_dir}/project_x/main.cxx builds into ${build_dir}/project_x/main.o. This way you are protected from name clashes when there are source files with the same name in different source directories. The compiler rule would look something like:
${obj_dir}/%.o : ${src_dir}/%.cxx # % includes directory name, e.g. project_x/main
#-mkdir -p ${#D}
${CXX} -c -o $# ${CPPFLAGS} ${CXXFLAGS} $<
Notice how in the above it creates the target directory on the fly. This is a bit simplistic, in a real-world build system object files depend (using order-only dependency) on its directory, so that make automatically creates the destination directory if it does not exist instead of speculatively trying to create them for each target object file even if it already exists.

Feedback about using make on a project with many subdirectories

To my Object Oriented Programming course, I must do a final proyect (academic purposes). I want to make a proyect "the right way" (ie: makefile, modular, DRY, easily scalable, etc) in order to better understand classes, makefile and C++.
The idea I've got is to have a "tree-source-file-structure-directory" so in each subfolder i'd got the source files with it's headers, test files and single makefile.
So if I want to work on the interface, I go to the subfolder interface, I edit the files, I run the tests, if everything is OK, simply I link the objects together on my root directory. Same thing if I want to work on my data structure, and so goes on. The nice feature is that in every subfolder resides along the source code and the object files, so the linker in my root directory would search for object files already compiled on subfolders and link them together
I've been searching on the internet, and I could see many different solutions:
-Doing make recursively, eg:
SUBDIRS=eda
.PHONY: subdirs $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $#
The problem I found is that my prerequisites on "eda" folder would be "quirky"
-Using Automatic Variable $(#D), but I didn't quite understand how it works
-Maybe using wildcard function, but I am a little confused about this option.
Anyways, the most tempting solution for me was the first one (using make recursively), but I found lot of comments saying that it is not recommended to use make recursively Interesting article
So I want to ask you guys some advices: How can I accomplish my objectives and have every important module in a separate folder? is recursive make the best solution? Maybe I should dive in "automake"? Or perhaps it would be better to take all the object files to a new "object" subfolder on root directory and then link them together?
By the way, I took the inspiration to make my proyect with this tree structure by sniffing Amarok source code: it has a subfolder called "src", and when you enter there, you can see a lot of subfolders: equalizer, playlist, dynamic, statusbar, core, playlistgenerator, playlistmanager, etc. And many subfolders have their own subdirectories... and the result is an incredible music player. If this method works fine to the Amarok team... I could be able to do something similar!
Any comments, feedback, suggestions and others are welcome, thanks in advance!
EDIT #1
Beta, I have some implicit rules (suffix) and a target for the linker that needs a object on my eda folder. Every other prerequisite of this target is built on the current folder.
The problem I have, is that when I run make to build that target, it takes the name of my prerequisite on "eda" folder as a target to build with the implicit rule. That's the tricky/unclean part of the makefile recursive on my proyect: I guess I must create a special implicit rule for every object file that make must search in a subfolder.
That's why I want some feedback: ¿Are there better alternatives? Or the advantages of using make recursive in my proyects overwhelm the other alternatives?
Anyways, if gives you better understanding, here is my draft Makefile (it is in spnish-english :P )
#Makefile hecho para las pruebas de los archivos dentro de esta carpeta
FLAGS=-g -DDEBUG
OUT_TI=TIndividuo
OUT_TP=TProfesor
OUT_TA=TAula
.SUFFIXES: .cpp .c .h .o
.c.o: ; cc $(FLAGS) -c $*.c
.cc.o: ; gcc $(FLAGS) -c $*.cc
.cpp.o: ; g++ $(FLAGS) -c $*.cpp
SUBDIRS=eda
.PHONY: subdirs $(SUBDIRS)
$(OUT_TI): eda/TAula.o CandidatoHorario.o TIndividuo.o TIndividuoTest.o TGen.o
g++ CandidatoHorario.o TIndividuo.o TIndividuoTest.o TGen.o eda/TAula.o -o $#
CandidatoHorario.o: CandidatoHorario.cpp CandidatoHorario.h
TIndividuoTest.o: TIndividuoTest.cpp TIndividuo.h
TIndividuo.o: TIndividuo.cpp TIndividuo.h
TGen.o: TGen.cpp
#eda/TAula.o: eda/TAula.cpp eda/TAula.h
# g++ -c eda/TAula.cpp -o $#
$(SUBDIRS):
$(MAKE) -C $#
clean:
rm -f *.o $(OUT_TI) $(OUT_TA) eda/TAula.o
The "Recursive Make Considered Harmful" is certainly a paper to read and to understand. Afterwards, your selection of tools should really be tailored to your specific projects.
For small projects that you initiate (or where you have the influence to guide high-level decisions), I would recommend spending a bit of time identifying your preferences (project layout, directory structure, unit test framework, etc.) and writing a generic set of makefiles that you will use for all your projects. You could easily end up with a generic master makefile, possibly a few more generic included makefiles for modularity (e.g. to build libraries, or unit tests or automatic dependency detection). You could also provide some extra flexibility with optional included configuration makefiles (e.g. specifying the order of your libraries). Most of the DAG construction would rely heavily on the content of your project directories. An example could look like:
include config.mk
sources := $(wildcard *.cpp)
programs := $(sources:%.cpp=%)
lib_sources := $(wildcard lib/*/*.cpp)
lib_dirs := $(sort $(patsubst %/, %, $(dir $(lib_sources:lib/%=%))))
lib_objects := $(lib_sources:lib/%.cpp=$(BUILD)/%.o)
all: $(programs:%=$(BUILD)/%)
.PRECIOUS: %/.sentinel %.d
# for dependencies on directories in build tree
%/.sentinel:
#mkdir -p $* && touch $#
clean:
$(RM) -r $(BUILD)
programs_aux:=$(programs)
include $(foreach program, $(programs), program.mk)
lib_dirs_aux:=$(lib_dirs)
include $(foreach lib_dir, $(lib_dirs), lib.mk)
# this should probably be in lib.mk
-include $(lib_objects:%.o=%.d)
The included program.mk (and lib.mk) would contain some boilerplate code to iterate over the lists of programs (and lists of libraries) and would factor out the specific parts of the makefile to build programs (and libraries).
To help with the implementation of such makefiles, you could use some standard library like http://gmsl.sourceforge.net.
This approach has several issues:
* it leads to makefiles that require strong skills
* it doesn't always scale very well to very large projects
* it relies heavily on "convention instead of configuration" and requires a clear upfront definition of the conventions that you will use (IMO this is good others might think that it lacks flexibility)
* life is too short to mess around with makefiles
Otherwise, I would suggest using higher-level configuration tools such as SCons or CMake as they tend to be conceptually simpler and they also allow other flavours of generators.

Which build system will do this the most 'naturally'?

Instead of the flat structure my code currently has, I want to organize it into modules contained in sub-folders (and perhaps sub-sub folders if the modules get big enough).
Each module will have one or more translation units which will each produce a .o file.
The final target would be to mash up all these object files into a static library (for now).
I am using plain 'make' and it is already complicated enough.
Is there a system in which the specified model comes naturally or with much less effort compared to writing makefiles by hand ?
(If you are going to recommend cmake, I need some hints as I have already tried and could not come up with a good solution.)
Some paraphrased bits from my current project's makefile that may help you out with good old fashioned GNU make:
SOURCEDIR := dir1 dir2/subdir1 dir3 dir4 dir5/subdir1 dir6/subdir1
SOURCES := $(foreach srcdir,$(SOURCEDIR),$(wildcard $(srcdir)/*.c))
OBJECTS := $(patsubst %.c,build/%.o,$(SOURCES))
OBJDIRS := $(addprefix build/,$(SOURCEDIR))
MAKEDEPS := $(patsubst %.c,build/%.d,$(SOURCES))
all: example
$(OBJDIRS):
-mkdir -p $#
build: $(OBJDIRS)
build/%.o : %.c | build
cc -MMD -c -o $# $<
example: $(OBJECTS)
cc -o $# $(OBJECTS)
-include $(MAKEDEPS)
In essence, it builds all of the source files found in the designated directories into object files located in subdirectories of the build directory in a hierarchy that parallels their source directory layout (important if multiple source files have the same name) and then links the results into an executable example.
As a bonus, dynamic dependency generation and inclusion via the MAKEDEPS variable and clang's -MMD flag.
It really depends upon your purposes: Build packages are generally intended for the audience rather than the performer. Often, they take into consideration the disparate environments into which people deploy. I played around with 'tup,' which seemed more a way of generating an executable as quickly as possible after an edit. 'Premake' seems to shoot at multiple platforms, but I found specifying compiler options no more enlightened than with Cmake.
It looks as though you've found a good Makefile tutor, so I'll leave my observations at that.

multi-directory "make" in linux programming

suppose we have a file-list:
src
a
b
c
Makefile
and there are many .cc & .h files in each folders.
how to write the Makefile??
when I write a path like this
./a/a.cc or ../a/a.cc
errors will be occurred.
but when i put the files on the same directory
and write as a.cc.
everything is ok.
I run it on cygwin.
could anyone help me?
The wildcard function is what you are looking for: http://www.gnu.org/software/make/manual/html_node/Wildcards.html
On Linux I would prefer Automake/Autoconf build systems: http://de.wikipedia.org/wiki/GNU_Build_System
An alternative could be CMake: http://www.cmake.org/
From the not-so-clear directory graph, it seems that you are missing the src/ directory prefix in your Makefile. E.g. to compile src/a/a.cc, use:
src/a/a.o: src/a/a.cc
$(CXX) $(CXXFLAGS) -c -o $# $<
BUT: Do yourself a favour, and use a real build system, such as CMake. It is cross-platform, can generate IDE project files (e.g. for Visual Studio, Xcode, Eclipse, CodeBlocks, etc.), is much higher level and does automatic dependency tracking for you.
You've left out a lot of details (e.g. where you want to put the object files), but VPATH is probably what you're looking for.
VPATH = src/a src/b src/c
# Now you can write rules as if the .cc & .h files were in the current directory.
%.o: %.cc
do something with $<
foo.o: foo.cc bar.h
do something special with $<