Multiple source files for one header Makefile - makefile

I have one header file Header1.h with multiple functions that are implemented in separate .cpp i.e. Func1.cpp, Func2.cpp.
So if I only had one header file and one cpp I would write:
Func1.o: Header1.h Func1.cpp
gcc -c Func1.cpp Header1.h
But writing:
Func1.o: Header1.h Func1.cpp
gcc -c Func1.cpp Header1.h
Func2.o: Header1.h Func2.cpp
gcc -c Func2.cpp Header1.h
does not work.

You wrote:
So if I only had one header file and one cpp I would write:
Func1.o: Header1.h Func1.cpp ; gcc -c Func1.cpp Header1.h
No, you wouldn't. You never put a header file on the compile line: the compiler will find the header file because of #include statements in the source file.
You would write this:
all: Func1.o Func2.o
Func1.o: Header1.h Func1.cpp
gcc -c Func1.cpp
Func2.o: Header1.h Func2.cpp
gcc -c Func2.cpp
However, this is really not a good makefile. First, your source files have a .cpp extension, which implies that they are C++ files, but you are using gcc, which is a C compiler. If your files are C++ files you should use g++ as the compiler.
Second, make already knows how to build an object file from a source file so you don't even need to write a rule.
Your makefile can just be:
CXX = g++
all: Func1.o Func2.o
Func1.o: Header1.h
Func2.o: Header1.h
and that's all you need.

Related

Compiling the file with a main function to a specific file name instead of "a.out"

I have multiple files that main.cpp depends on. My main.cpp file contains int main() {...} in it. Currently, my command to compile main.cpp looks like so:
g++ main.cpp src_file1.cpp src_file1.cpp header.h ...
This generates a.out. I do not want this file to be named a.out. I want to control the main executable's file name. I tried using this command to do so:
g++ main.cpp src_file1.cpp src_file1.cpp header.h ... -o main.out
However, when I run this, I get the error:
error: cannot specify -o when generating multiple output files
I understand why this is happening, but I do not know how to fix it. Of course I still want g++ to compile my headers and other c++ files, but I would like the main file, main.cpp to be compiled as main.out instead of a.out. How can I do this?
Relevant makefile code (if you want):
SRC = block.cpp list.cpp blocker.cpp hasher.cpp header.h
CFLAGS = -g -Wall
CC = g++
STD = -std=c++11
ARGON = argon2/libargon2.a
TARGET = main.out
main: main.cpp $(SRC) argon2/argon2.h
$(CC) main.cpp $(SRC) $(ARGON) $(CFLAGS) $(STD) $(TARGET)
Don't pass header files to the compiler as if they were source files. Try this:
SRC = block.cpp list.cpp blocker.cpp hasher.cpp
ARGON = argon2/libargon2.a
TARGET = main.out
main: main.cpp $(SRC) argon2/argon2.h header.h
$(CC) main.cpp $(SRC) $(ARGON) $(CFLAGS) $(STD) -o $(TARGET)

make is calling g++ is always re-compiles even when I do not change the source code

I am using make which calls g++ always re-compiles the code, even when I do not change the source code. That happens for all my projects, even for simple ones such as:
[code]
all: main.cpp
g++ -std=c++11 -c main.cpp
[/code]
I believe it should compare the date/time on source and object code. Could some help me with this, I am running using GNU toolchain on Ubuntu 12.04
THX
Edit: sorry guys, I do use Makefile, I edited my question accordingly.
Simplest Makefile
It was already pointed out that your Makefile is probably wrong. The 'all' target is indeed always built (although it may result in a no-op if it has no commands and all dependencies are already satisfied). All you need in your makefile is this:
all: main
Object files
If you expect to have more source file in your build, you should consider creating intermediate object files:
all: main
main: main.o
Tweak the build
Make will automatically find the main.ccp file and turn it into main which is required per the directive above. You can use special make variables to further tweak the compilation, e.g. for debug information inclusion and for warning configuration:
CXXFLAGS = -g -Wall -Werror
all: main
main: main.o
Nitpicking
If you insist on building up the compile rule yourself, you can do it like this:
%.o: %.hpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
CXX: C++ compiler
CPPFLAGS: C preprocessor flags
CXXFLAGS: C++ compiler flags
$#: Target
$<: First dependency
If you don't want to use the standard variables nor pattern matching, you can build up the whole makefile explicitly:
all: main
main: main.o
gcc -o $# $^
main.o: main.c
gcc -g -Wall -Werror -o $# -c $<
$^: Use that one if you want to include all dependencies, for example if you have multiple *.o files to build one binary.
Note: It is a bad idea to write the file names directly into the command as you might forget to update them later.
all: main.cpp
g++ -std=c++11 -c main.cpp
This seems wrong. Why does the rule for all has main.cpp as its target? Shouldn't it be something.exe or something.o? Say
all: main.exe
main.exe: main.cpp
g++ -std=c++11 main.cpp -o main.exe
clean:
del main.exe
Targets are output files and cpp files are source code which should be input to the make system.
g++ would have to "recompile" in general (what happens if you change the header but not main.cpp?)
If you are concerned about long build times, you should use something like Make (which is designed specifically to avoid recompiling when the source hasn't changed)
The compiler will always compile the code. If you want to do conditional compilation (based on file times etc) you will need to use a make system such as Make, CMake, Ant, etc. For the simplest you can set up a small "Makefile" in the directory and use the command "make" to build.
Simple Makefile for compiling "myapp.exe" from "main.cpp", "file1.cpp" and "file2.cpp"
myapp.exe: main.o file1.o file2.o
g++ -o myapp.exe main.o file1.o file2.o
(make knows to use .cpp files to build .o files)
But if you also have header files, then you will need to build dependency chains, for which you may want to look into something more sophisticated like automake, cmake, ant, etc.
---- EDIT ----
Based on your updated post, the problem is that you aren't specifying a target, so Make has to assume it needs to recompile. See my example in the above answer.

Order of the lines on makefile

I have main.cpp (including main function) and func1.cpp, and I want to link these files with a makefile. Classic form would be:
main: main.o func1.o
g++ main.o func1.o -o main
main.o: main.cpp
g++ -c main.cpp
func1.o: func1.cpp
g++ -c func1.cpp
or one can write
main: func1.o main.o
g++ main.o func1.o -o main
func1.o: func1.cpp
g++ -c func1.cpp
main.o: main.cpp
g++ -c main.cpp
or
main: main.o func1.o
g++ main.o func1.o -o main
func1.o: func1.cpp
g++ -c func1.cpp
main.o: main.cpp
g++ -c main.cpp
Do the last two differ from the classic one ? Does one have some advantages over the other?
No, the only time the order of the rules comes into play is when you just enter make, in which case it can choose the first rule as the default.
Beyond that, make is intelligent enough to execute dependent rules no matter where they are in the file.
There is no difference between the three sets of ruls. However, make knows how build .cpp files into object files, so all you really need is:
main: main.o func1.o
g++ main.o func1.o -o $#

how can I compile header and its run file without main

I have two files without main
X.h
X.cpp
I want compile these in one makefile
My makefile is ;
CXX = g++
CXXFLAGS_W = -Werror -Wunused-variable -Wunused-value -Wunused-function \
-Wfloat-equal -Wall
CXXFLAGS_M = -ansi -pedantic-errors
CXXFLAGS = ${CXXFLAGS_M} ${CXFLAGS_W}
all: main
./main
When I use like make X , compiler gives some error "undefined reference to main ". Due to that reason, I want new makefile. X can be any name .
You would generally have something like:
X.o: X.cpp X.h
g++ -c -o X.o X.cpp # or $(CXX) $(CXXFLAGS) -c -o ...
with whatever other flags you needed. -c tells the compiler to just compile rather than compile and link, and you don't usually compile the header file directly, rather you #include it in the cpp file.
Here's a makefile which combines two separate source files into a single executable:
xy: x.o y.o
g++ -o xy x.o y.o
x.o: x.cpp x.hpp y.hpp
g++ -c -o x.o x.cpp
y.o: y.cpp y.hpp
g++ -c -o y.o y.cpp
The x.cpp file includes x.hpp and y.hpp while y.cpp only includes y.hpp. The final executable is xy.
The first rule builds the executable from the two object files. The second and third rules builds the two object files, which is what I think you're asking for in the question.

is it possible to create an object file from other object files in gcc?

I was trying to do something like this in a makefile:
program.exe: ui.o main.o
gcc ......etc
ui.o: window1.o window2.o
gcc -c window1.o window2.o -o ui.o #this doesn't want to work
window1.o: window1.c window1.h window1_events.c window1_controls.c ...
gcc -c window1.c window1_events.c window1_controls.c... -o window1.o
window2.o: ...
gcc ...
main.o: ...
gcc ...
but when I compile like this, it gives the error "input file unused because linking not done," and then I get a bunch of unresolved externs, etc--problems which are resolved by changing
program.exe: ui.o main.o
gcc ...
to
program.exe: window1.o window2.o main.o
gcc ...
so is it possible to just link object files together, to avoid having mile-long lines in a makefile and break down the build process a little more?
Yes: to merge several object files into one, use ld -r or ld -Ur:
From "man ld" on Linux:
-r
--relocatable
Generate relocatable output---i.e., generate an output file that can
in turn serve as input to ld. This is often called partial linking.
As a side effect, in environments that support standard Unix magic
numbers, this option also sets the output file’s magic number to
"OMAGIC".
If this option is not specified, an absolute file is produced.
When linking C++ programs, this option will not resolve references to
constructors; to do that, use -Ur.
You could also do this with gcc:
gcc -Wl,-r foo.o bar.o -o foobar.o -nostdlib
Merging object files like this has some advantages over using an archive library: if merged files change very infrequently (compared to say main.c), your final executable links will be faster.
OTOH, with archived library, the linker will only use what it needs, so your executable may end up being smaller if e.g. window2.c ends up not being necessary.
I bunch of object files is a library. You can create a library with the ar
utility. The following example creates a library called mylib.a containing the files foo.o and bar.o
ar rvs mylib.a foo.o bar.o
You can then link with it by using it on the compiler command line:
gcc -o myexe main.c mylib.a
To create a library:
ar rvs somelib.a file1.o file2.o file3.o
To link it:
gcc -o program.exe file4.o somelib.a

Resources