When compiling:
C++ files are compiled to generate machine language files
The machine language files are then linked to generate an executable file
Q: If a C++ source file changes, what must be re-done?
A: The file that was changed must be re-compiled and the machine language file must be re-linked.
It is not necessary to recompile source code files that have not changed.
Note that if an include/header file is changed, then any file that includes the changed include file has effectively been changed and so must be recompiled.
In UNIX, the most recent modification time for a file is stored.
The ls -l
, or ll
, command shows the most recent modification time for a file.
For example, if a .cpp
has a more recent modification time, then the corresponding .o
file will not match the more recent .cpp
file.
Example:
bash> ls -l
-rw-r--r-- 1 file_owner group 1286 Sep 5 10:15 file.cpp
-rw-r--r-- 1 file_owner group 986 Sep 5 10:12 file.o
-rw-r--r-- 1 file_owner group 826 Sep 5 10:10 file.h
bash>
file.cpp
has been changed, it must be recompiled.
make
CommandThe make
command may be used to automate compiling.
The make
command when executed will look for a file named makefile and then, if not found, for a file named Makefile to specify dependencies. Otherwise, a makefile must be specified with the -f
option.
The make
command has some rules built-in so it can do some basic compiling, but usually the developer provides a makefile.
Makefile rules have the form:
target: dependency_list
TAB command
|
A file or name. |
|
Files that the target "depends on". |
|
The TAB character. REQUIRED! |
|
Typically a compiling/linking command, but can be any command. |
If the modification time of any dependency is more recent that the target, the command lines are executed.
If the dependency list is empty, the command lines are always executed.
Creating machine language, .o
files and linking are two things that must be done.
# Link
executable: file_1.o file_2.o
clang++ -Wall file_1.o file_2.o -o executable
# Create .o file
file.o: file.h file.cpp
clang++ -Wall -c file.cpp
Note: .cpp
files are typically not targets, .cpp
files do not depend on other files.
make
If the make
is run with no arguments, the makefile is used and the first rule is run. Other than this, the rule order does not matter.
A rule, for example clean, may be specifier as an argument and make
will run that rule.
KEY POINT:
Before processing a rule, make
looks at each file in the dependency list to see if it is the target of another rule. If it is, then that other rule is processed before the current rule.
# This is a comment line, like // in C++
# Create the executable is the first rule here
# Link
main: bigint.o main.o
clang++ -Wall bigint.o main.o -o main
# Create .o file
main.o: bigint.hpp main.cpp
clang++ -Wall -c main.cpp
# Create .o file
bigint.o: bigint.hpp bigint.cpp
clang++ -Wall -c bigint.cpp
# Remove .o and executable
clean:
rm -f *.o
rm -f main
Again, the space in front of the commands must be TAB characters.
*
does pattern matching, it matches any sequence of characters.
*.o
will match all files with the .o
extension.
Be careful, *.* .o
will match all files and a file named jsut .o
.
rm * .o
will remove/delete all files in the current directory. There is no trash that files can be recovered from.
make # Run, use first rule
make clean # Run, use the rule with "clean" target
make -n # Output the commands that would be executed, don't execute them
make -f file # Use file as the "makefile"
If you change the makefile and re-run it, nothing will happen if the files are up-to-date. Use touch
command on a file.
touch file.cpp # Make last modification time the current time, create if non-existent