Makefile for compiling a number of .cpp and .h into a lib - c++

I am running Windows 7 with gcc/g++ under Cygwin. What would be the Makefile format (and extension, I think it's .mk?) for compiling a set of .cpp (C++ source) and .h (header) files into a static library (.dll). Say I have a variable set of files:
file1.cpp
file1.h
file2.cpp
file2.h
file3.cpp
file3.h
....
What would be the makefile format (and extension) for compiling these into a static library? (I'm very new to makefiles) What would be the fastest way to do this?

The extension would be none at all, and the file is called Makefile (or makefile) if you want GNU Make to find it automatically.
GNU Make, at least, lets you rely on certain automatic variables that alone give you control over much of the building process with C/C++ files as input. These variables include CC, CPP, CFLAGS, CPPFLAGS, CXX, CXXFLAGS, and LDFLAGS. These control the switches to the C/C++ preprocessor, compiler, and the linker (the program that in the end assembles your program) that make will use.
GNU Make also includes a lot of implicit rules designed to enable it automatically build programs from C/C++ source code, so you don't [always] have to write your own rules.
For instance, even without a makefile, if you try to run make foobar, GNU Make will attempt to first build foobar.o from foobar.c or foobar.cpp if it finds either, by invoking appropriate compiler, and then will attempt to build foobar by assembling (incl. linking) its parts from system libraries and foobar.o. In short, GNU Make knows how to build the foobar program even without a makefile being present -- thanks to implicit rules. You can see these rules by invoking make with the -p switch.
Some people like to rely on GNU Make's implicit rule database to have lean and short makefiles where only that specific to their project is specified, while some people may go as far as to disable the entire implicit rule database (using the -r switch) and have full control of the building process by specifying everything in their makefile(s). I won't comment on superiority of either strategy, rest assured both do work to some degree.

There are a lot of options you can set when building a dll, but here's a basic command that you could use if you were doing it from the command line:
gcc -shared -o mydll.dll file1.o file2.o file3.o
And here's a makefile (typically called Makefile) that will handle the whole build process:
# You will have to modify this line to list the actual files you use.
# You could set it to use all the "fileN" files that you have,
# but that's dangerous for a beginner.
FILES = file1 file2 file3
OBJECTS = $(addsuffix .o,$(FILES)) # This is "file1.o file2.o..."
# This is the rule it uses to assemble file1.o, file2.o... into mydll.dll
mydll.dll: $(OBJECTS)
gcc -shared $^ -o $# # The whitespace at the beginning of this line is a TAB.
# This is the rule it uses to compile fileN.cpp and fileN.h into fileN.o
$(OBJECTS): %.o : %.cpp %.h
g++ -c $< -o $# # Again, a TAB at the beginning.
Now to build mydll.dll, just type "make".
A couple of notes. If you just type "make" without specifying the makefile or the target (the thing to be built), Make will try to use the default makefile ("GNUMakefile", "makefile" or "Makefile") and the default target (the first one in the makefile, in this case mydll.dll).

Related

Retrieve used header and source file names by parsing Makefile

I would like to extract all the *.cc and *.h filenames from a Makefile that also contains unused targets. Example Makefile here : https://gist.github.com/berceanu/7554a9c4371b807e425259c7e99b5de9
I've tried running make -Bnd and looking at the pruned files but I don't know if this misses anything.
make -Bnd | grep "Pruning file" | sort | uniq
Expected result: list of all *.h and *.cc files used by make run on the above Makefile.
Your approach trying to extract this information from the Makefile is probably the wrong way. make doesn't know which header files are actually used. make only knows which header files you've explicitely told make about in the dependencies, and that's not very reliable. The information in the Makefile could be wrong in two ways. It could contain unused targets (as you have noticed) or unused header files. It could miss header files that are actually included but not mentioned in the Makefile. Even worse, what if the actual inclusion of header files depends on macros, like #ifdef XYZ_FEATURE #include "additionalHeaderFile.h" #endif.
There are at least three ways how you could generate the desired list, that is, list of .cc and .h files actually used during compilation:
(blindly trusts the Makefile) make -n --print-data-base
(follows the real files of the build, but also a bit difficult to parse) strace -f make
(relies on a feature present in GCC, clang, armcc and possibly other compilers for Makefile generation, very reliable) Add CPPFLAGS:=-MMD to the Makefile, run make clean, then make, then use cat *.d to get the list of all .cc and .h files used to build run. You could even do that without changing the Makefile: make clean; make CPPFLAGS:=-MMD && cat *.d | sed -e 's/\\//g' -e 's/:/ /g' -e 's/ \+/\n/g' | sort -u.
Also, the Makefile that you've shared in the gist has a large number of issues.
The default target should, by convention, be named all 1 2 3. That doesn't need to be the name of the binary, it would just be a .PHONY target.
The variable with the list of object files should be named OBJS or OBJECTS, not OBJ. The name OBJ is misleading, because it's singular.
Instead of rm use $(RM) which implies -f and thus will not trouble in case a file doesn't exist. (As a side-effect, the Makefile would become more portable, as not all platforms use rm for deleting files.)
clean is not a file and thus should be a .PHONY target.
clean should use :: instead of : for its recipe so that in future, when the Makefile is bigger and split into multiple files, each file can have their own clean target without problems.
Variables that are not rule-specific should be expanded at the moment of definition, not when they are referenced, and thus defined using := instead of =.
Instead of C++ use CXX which is already defined.
Instead of putting the options into C++/CXX, use LDFLAGS, because you're linking.
You should have a source file that has the same basename as the binary. Then you can use the built-in rule for linking.
Explicit dependencies in the Makefile are a pain for maintenance. Every time an #include statement for a project header file is added, removed, or changed, the Makefile would have to be updated, and that's easy to forget, and it's a pain, especially when the #include statement is in a header file. Even with due diligence, this is also an invisible merge conflict. Instead of having explicit dependencies in the Makefile, you should use CPPFLAGS+=-MMD at the start of your Makefile and append -include $(wildcard *.d) at the end of your Makefile, and add *.d to the list of files to delete in clean. You could then remove all dependency rules from the Makefile (except for the one for the linkage).
Naming the binary run is not a good idea. Users that see that your Makefile has a run target would expect this to run the actual program, not to link it.
It is better to have each object mentioned on a line of its own. That significantly reduces merge conflicts in projects when multiple developers change the object list at the same time.
Your actual Makefile should look like this, with the binary renamed from run to program:
LDFLAGS:=-Wno-deprecated -lm
CPPFLAGS+=-MMD
BINARY:=program
OBJECTS:= \
$(BINARY).o \
binomh.o \
# More objects here
.PHONY: all
all: $(BINARY)
$(BINARY): $(OBJECTS)
.PHONY: clean
clean::
$(RM) \
$(BINARY) \
*.[adios] \
-include $(wildcard *.d)
That Makefile will do the "same" thing as your Makefile, but it is almost maintenance-free. No need to update dependencies, as they are automatically taken from the dependency files generated by the C Preprocessor. The *.[adios] will also remove files created in case you added -save-temps to any of the CFLAGS, CXXFLAGS, or CPPFLAGS.
This type of Makefile is known to work for GCC, clang, AOCC (AMD Optimizing C Compiler), and armcc. It probably works for a number of other compilers and preprocessors as well, especially when they are based on, or try to be compatible with, GCC or clang/LLVM.
BTW in case you're interested in knowing that this works for you, with high confidence, besides experience: I've taken your Makefile and added the following lines to it in order to reproduce your source code structure. The header files would just be empty files. The C++ source files would be lists of #include statements taken from the dependencies in your Makefile.
%.cc:
grep '^$*\.o.*:' $(MAKEFILE_LIST) | sed -e 's/.*://' -e 's/.*$*\.cc//' -e 's/ \([^ ]\+\)/#include "\1"\n/g' >$#
%.h:
touch $#
Instead of -Bnd, I would suggest using --dry-run --print-data-base to dump the full database of targets, their dependencies, rules, variables, etc..

can you create a c++ file from an .o object file with makefile?

What I'm trying to do is create a c++ file from an object file but I cannot figure out a way to do so.
INCLUDEDIR = ../headers
CXXFLAGS = -std=c++11 -I $(INCLUDEDIR) -Wall -Wfatal-errors -O2
all:primeFactors.o
primeFactors.o: primeFactors.cpp $(INCLUDEDIR)/primeFactors.h
g++ $(CXXFLAGS) -c $< -o $#
When I try to build this I get
make: *** No rule to make target 'primeFactors.cpp', needed by
'primeFactors.o'. Stop.
which I understand but when I take out the primeFactor.cpp argument I then get told there is nothing to be done with the make file. So is there a way to do this?
In general; no, you cannot do that. An object file (.o file) is the result of the code passing through the compiler front-end (to parse the language) the optimizer (to make it run fast) and the compiler back-end (to produce code that will run on your CPU).
This process is not reversible. You cannot go from compiled code back to source.
can you create a c++ file from an .o object file with makefile?
A makefile will allow you to do that only if you have an underlying tool to do it. make, which uses makefiles to do its job, does not have any built-in mechanisms to pull that off.
Your makefile has a rule for building primeFactors.o.
primeFactors.o: primeFactors.cpp $(INCLUDEDIR)/primeFactors.h
It says that primeFactors.cpp and $(INCLUDEDIR)/primeFactors.h are needed to build primeFactors.o. If you don't have those files, or no rules to build them, there is no way for make to build primeFactors.o.

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).

How to use a library with headers and .so files?

I'm new to C and wanted to use a library (MLT Multimedia Framework)
I've built it and it produced the following directories: include lib share
Inside lib there are .so .a .la files
Inside include there are .h files
Now, I'm instructed to do this:
#include <framework/mlt.h> which is inside include/mlt/framework/
Questions:
Why I do I need to place the header file that contains only function prototypes? Where are the real functions then? are they linked someway to the ones included in lib directory?
Where to place my own files and how to compile it?
How to learn more about the topics:
Dynamic/Static libraries
Building / making / installing
How to use any C library
If you don't have the function prototypes, how would the compiler know what functions exist in the library? Short answer is: It doesn't. Longer answer: The compiler doesn't care about library files, static (files ending in .a) or shared (files ending in .so), all it cares about is the current translation unit. It's up to the linker to handle resolving undefined references.
When you use libraries, you include the header files that contain the needed declarations (structures, classes, types, function prototypes) into the source file. The source file plus all included header files forms the translation unit that the compiler uses to generate code. If there are undefined references (for example a call to a function in the library) the compiler adds special information about that to the generated object file. The linker then looks through all object files, and if it finds an unresolved reference it tries to find it in the other object files and the provided libraries. If all definitions are resolved the linker generates the final executable, otherwise it will report the unresolved definitions as errors.
To answer your other questions:
Where to place my own files and how to compile it?
This is two questions, the answer to the first one (about placement of your files) is that it doesn't really matter. For small project with only a few source and header files, it's common to place all files in a common project directory.
The second question, about compiling, there are different ways to do it too. If there are only one or two source files you could use the compiler frontend (e.g. gcc) to compile and link and generate your executable all in one go:
$ gcc -Wall -g source1.c source2.c -o your_program_name
The above command takes two source files, compiles and links them into the program your_program_name.
If you need to use a library, there are one or two things that you need to add to the above command line:
You need to tell the linker to link with the library, this is done with e.g. the -l (lower case L) option:
$ gcc -Wall -g source1.c source2.c -o your_program_name -lthe_library
It's important to note that the_library is the base name of the library. If the library file is named libthe_library.so then only the_library part is needed, the linker will add the other parts automatically.
If the library is not in a standard location, then you need to tell the compiler and linker where the library file are. This is done with the -I (capital i) option to tell the preprocessor where the header files are, and the -L (capital l) where the linker files are.
Something like
$ gcc -Wall -g -Ilocation/of/headers source1.c source2.c -o your_program_name -Llocation/of/libraries -lthe_library
If you have more than a couple of source files, it's common to use so called makefiles that lists all source files, their dependencies, compiler and linker flags, and contain rules on how to build object files and link the final program. Such a makefile could look like
CFLAGS = -Wall -g
LDFLAGS = -g
SOURCES = source1.c source2.c
OBJECTS = $(SOURCES:.c=.o)
TARGET = your_program_name
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LD) $(LDFLAGS) $^ -o $#
%.o: %.c
$(CC) $(CFLAGS) $< -c -o $#
The above makefile should do just about the same as the previous command line. The big difference is that it's much easier to add more source files, add special rules for special files, and most importantly, the make program will handle dependencies so that if one source file haven't been modified since last build then it won't be compiled. The last bit will make big projects with many source files build much quicker when only one or a few source files has been modified.
How to learn more about the topics [...]
By going to your favorite search engine, and looking for those topics there. I also recommend e.g. Wikipedia.
Of course, if you use an Integrated Development Environment (a.k.a. an IDE) then you don't have to compile from the command line, or to make your own makefiles, the IDE will handle all that for you. It will also have dialogs for the project settings where you can enter include paths and library paths, and what libraries to link with.
Why I do I need to place the header file that contains only function prototypes?
So as to satisfy your compiler for declaration of those functions or declaration of classes. As C++ is static type checking language, they must know the type of objects which they will be using.
Where to place my own files and how to compile it?
You can place you code anywhere in you filesystem; only make sure to include .h files in includes path and lib while compiling. Usually you need to modify your path.
You can check about building on this link:
https://en.wikipedia.org/wiki/GNU_build_system
Check the README file that came with the code. It should tell you how to install it into the system properly. Usually there is an install build target which installs the resulting files into the proper directories.
The usual sequence of commands to build and install most products is:
$ ./configure
$ make
$ sudo make install

Portably Compile Entire Directory

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.