C and C++ cmake tutorial from scratch

  • 2020-06-12 10:05:18
  • OfStack

C/C++ CMake tutorials from scratch

If you've ever installed a piece of software on an linux system with source code, you'll be familiar with all three steps # 1 - Configuring (configure), compiling (make), and installing (make install). Almost every time it's a robotic operation, behind it is make (GNU, to be exact) doing a lot of quiet work for you.

1. Compile ES16en. c -- compile a single 1 source file


//hello.c
#include <stdio.h>
int main(){
 puts("hello, world!");
 return 0;
}

To compile and generate the corresponding executable, you might use the following command:


$ cc -o hello hello.c
$ ./hello
hello, world!

However, using make (as long as you have both GCC and GNU Make installed on your operating system) is a bit more refreshing.


$ make hello
cc hello.c -o hello
$ ./hello
hello, world!

1.1 write Makefile

What? You can't even write "make hello"? By the end of this section, all you have to do is slowly type four letters of "make" and press enter, which is easier than IDE (at least you won't have to look around for the damn "run" button.

Just create a new file in the same directory as hello.c as the configuration file for the make command. It's simple:


hello:

1.2 Set the compiler

What? You don't want to use the default cc, but gcc to compile your program? That's not easy, just assign the value of the CC variable to gcc in the Makefile file.


CC := gcc
hello:

If you want to run make at this point, please note that make does not recompile to generate hello at all. Why? Because make is "lazy", because it detected hello.c and the last compilation of 1 modular 1, then recompile the generated executable must be the same ah, then there is no need to run, directly return the result. This is where the little tricks come in. make is easy to trick anyway. Enter the following command to update the last modification date of ES64en.c.


$ touch hello.c

Or simply delete the hello file. But there are good and bad ways to delete files, if you use the following command:


$ rm -f hello

This is a low blow, as it is possible to delete other important source files with a 10 point penalty. So what's the big idea? Add the following to Makefile:


clean:
 $(RM) hello

The operation mode is also very simple, just run the make clean command.

1.3 Add compilation options

If you want to add the -ES84en-ES85en-ES86en option to gcc, just set the value of the variable CFLAGS.


CC := gcc
CFLAGS := -g -Wall -Wextra
hello:
clean:
 $(RM) hello

At this point, the results of running make clean and make are as follows:


$ make clean
rm -f hello
$ make
gcc -g -Wall -Wextra hello.c -o hello

2. Chunking -- Compiling a program with multiple source files

If your program no longer has only one source file, you can easily write Makefile files in combination with Make's built-in compilation rules to complete the compilation. Here is a simple example:


$ cc -o hello hello.c
$ ./hello
hello, world!
0

The program needs to use ncurses, which is the basic library for 1-character terminal screen control, so the -lncurses option needs to be added at the end of compilation. At this point, you may have noticed that writing Makefile is mostly about writing dependencies, block: block.o function.o This means that block is generated from the block.o and ES110en.o links. At the same time, bolck.o and ES115en.o are compiled from bolck.c and ES119en.c as required, because make has the following built-in rules: *.o is generated by the source file of the same name, so there is no need to write redundant bolck.o:bolck.c and function.o:function.c . The results are as follows


$ cc -o hello hello.c
$ ./hello
hello, world!
1

3. Built-in rules for Make

The input make -p Command to see all the built-in rules of make. For example, the *.o mentioned above was generated by the c source file with the same name. The output of ES136en-ES137en is shown as follows:


$ cc -o hello hello.c
$ ./hello
hello, world!
2

Where % is the wildcard and $(COMPILE. c) is the value of the variable COMPILE. c


#  The default 
COMPILE.C = $(COMPILE.cc)

In the further step, we get:


$ cc -o hello hello.c
$ ./hello
hello, world!
4

The above variables can be re-assigned as in the previous instance (null by default) to customize the compilation.

Automatic variables

In addition to variables in the form of $(COMPILE.c) and $(COMPILE.cc), there is a very common and extremely important class of variables in make -- automatic variables.
The most commonly used automatic variables are listed below:

The generation target of the $@ rule File name element in the $% file member structure $ < The first dependent file name $^ All dependent file names (de-weighted), separated by Spaces $+ all dependent filenames (unweighted), separated by Spaces $* All dependent filenames with suffixes removed, separated by Spaces, apply only to schema rules. Note: The file name contains stem and suffix. Remove suffix to leave stem. For example, hello.cpp's stem is hello and suffix is cpp. $& # 63; New dependencies than the target file.

Consider this rule:


$ cc -o hello hello.c
$ ./hello
hello, world!
5

LINK.c is defined as follows:


$ cc -o hello hello.c
$ ./hello
hello, world!
6

CC is defined as follows:


$ cc -o hello hello.c
$ ./hello
hello, world!
7

And CFLAGS, CPPFLAGS, LDFLAGS, TARGET_ARCH are empty by default.
Finally, the original rule is equivalent to:


%: %.c
 cc $^ -o $@

Therefore, for the compilation of hello at the beginning of this article, simply read Makefile:


$ cc -o hello hello.c
$ ./hello
hello, world!
9

You get the final compilation command:


cc hello.c -o hello

So, reference make -p make has built-in rules for command output. Makefile is a good way to write your own programs and learn how to use Make proficiently.

conclusion


Related articles: