Location>code7788 >text

Linking from compilation to cmake

Popularity:595 ℃/2024-11-06 02:16:35

.c (.cpp) files to executables

For a simple .c/.cpp-suffixed source file, the language used is human-readable and understandable, but for a computer, it is the binary machine code that can be understood and executed.

That is, all a computer can run is binary machine code, which was earlier replaced by the use of simple mnemonics to make it easier for humans to read, such asMOV,LOOP...etc., and in order to further increase the readability of programming, the c language was born, as well as a host of subsequent high-level languages, such as c++, python, and so on.

#include <>
int main()
{
    printf("Hello, world!\n"); return 0; int main() { printf("Hello, world!
    return 0; }
} // Human language, computer can only execute 0101010101 .... Duplicate machine code

So to make the c or cpp code we write into binary machine code that the computer can execute, we need to use some program to compile the source code into executable binary machine code by some means.

In general, the workflow of the compiler is as follows:

  • Preprocessing: The macros in the source code are subject to all macro expansion, macro replacement, and conditional compilation operations, and there are no macro definitions in the file after this operation. (.i file)
  • Compilation: the preprocessed file is passed through the lexical analysis, syntax analysis, semantic analysis, optimization, code generation and other operations of the compiler to generate the corresponding assembly language file (.s file)
  • Assembly: assembly language files are assembled by assembler compilation operations to produce corresponding machine code files (.o files)
  • Linking: multiple .o files are linked to produce the final executable (.exe file/no suffix under linux)

Therefore, what the compiler does is to convert the source code into machine code by means of its own set of rules. The rules are generally defined by a corresponding language standard, and the compiler can just implement the standard through different implementations. A compiler is more like a translation program, and its job is to translate from one language to another according to human translation needs. Common compilers are gcc (open source), clang (jetbrain series), msvc (Microsoft), etc. Different compilers support different latest standards.

As for where the compiler comes from, do a web search.

The compiler used for this training is gcc, which can be accessed using thegcc --versioncommand to view the current gcc version.
If gcc is not installed, you can usesudo apt-get install build-essentialcommand to install gcc.

Let's take gcc as an example to see how to compile a .c/.cpp file into an executable file step by step.

#include <>
#define first 1
int main()
{
    printf("Hello, world!\n");
    int num = first;
    printf("%d", num);
    return 0;
} // suppose that...

preprocessing

In the terminal, typegcc -E -o Command.-Eoption indicates pre-processing only.-ooption specifies that the output file name is
Then openfile, you can see the pre-processed source code as follows:

# 0 ""
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/" 1 3 4
.....//Omit a bunch of stuff here.
int main()
{
    printf("Hello, world!\n");
    int num = 1;
    printf("%d", num);
    return 0;
}

If we go back to the .c file, we look at thestdioThis header file can be found to have the same contents as theThe front of the file is the same, except that the macros in the header file are directly in the path where the header file is located. And the macros we definefirsthas also been replaced with1

compiling

In the terminal, typegcc -S Command.-Soption means that the file will be compiled and the output file will be a translation of the compiled.sDocumentation.
Then openfile, you can see that the compiled source code is as follows:

	.file ""
	.text
	.section .rodata
.LC0:
	.string "hello world!"
.LC1:
	.string "%d"
	.text
	.globl main
	.type main, @function
main:
.LFB0:
	.cfi_startproc
	endbr64
	pushq %rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq %rsp, %rbp
	.cfi_def_cfa_register 6
	subq $16, %rsp
	leaq .LC0(%rip), %rax
	movq %rax, %rdi
	movl $0, %eax
	call printf@PLT
	movl $1, -4(%rbp)
    ........;lit. omit a bunch of

As you can see, the c language is changed into a much less readable assembly language by the compiler, but there are still some things that are human readable such asmovcalletc. instructions.

compile

In the terminal, typegcc -c Command.-coption indicates that the file will be compiled and the output file will be a binary file
image

You can see that it has indeed become a binary file, and since there is no corresponding decoder, you can't see the contents directly.

link (on a website)

link to binary file

By linking, I mean linking multiple.ofiles are linked to generate the final executable. For linking, for the compilation of multi-file projects, because an executable file may contain multiple source files, and these source files may contain different functions, so you need to link the functions in these source files to generate the final executable file.

For the abovefile, and since it's a single file, you can simply use the
gcc -o helloGenerating executable fileshellothen run

./hello
Hello, world!

This is not true for multiple files, for example, we have two files:

int sub(int a, int b)
{
    return a - b;
} // 
#include <>
int sub(int a, int b); // declare the sub function
int main()
{
    int a = 10, b = 5; int result = sub(a, b); // declare sub function
    int result = sub(a, b); printf("%d, result); // Declare the sub function.
    printf("%d", result); } // Declare sub(int a, int b); // Declare sub(int a, int b).
} //

If you directly use thegcc -c Generating the executable returns the following error:

:(.text+0x25): undefined reference to `sub'

That is, the definition of the sub function cannot be found, which is obvious; the sub function is implemented in theMiddle.in which we just told the compiler that there was a functionsubThis behavior is not reported as an error during preprocessing->compilation->assembly, but during linking, the compiler is unable to locate thesubimplementation, so a link error was reported.

So to not report an error, you can do this:
gcc -o mainThis way the compiler will compile the two files into a binary file and will take part in the linking process to produce the final executable file main. note that it is the binary file that is linked, not the source file.

For the method of using multiple binaries to participate in linking to generate executables, the advantage is that, by splitting the project into multiple modules, when changes are to be made to a part of the project, it is only necessary to recompile the module as a new.ofile without recompiling the entire project.

Library file links

A library file is some pre-compiled binary file that can be shared by multiple programs. They are categorized into dynamic libraries(.so file under linux / .dll file under windows)and static libraries(.a file under linux / .lib file under windows)The difference. The difference is that static libraries are linked into the executable at connection time, while dynamic libraries are linked into the executable at runtime. Here will not demonstrate the use of gcc to generate and link the library file process, you can refer to the relevant information.

At this point, we've walked through the entire process of how to get from source code to executable.

cmake

As you can see, for larger projects, using thegcccommands to compile would be cumbersome and troublesome, just like going from machine code to assembly to C. In order to simplify the compilation process, there are commands from thegcc -> makefile -> CMakeListsSuch a change.

A brief introduction to makefile

Makefile is a tool for managing the build process of a project and is widely used for compiling languages such as C/C++. It greatly simplifies the developer's work by defining rules and instructions to automate the compilation and linking steps. In other words, makefile tells the compiler how to compile the source code, how to link the libraries, and how to generate the executable file through some rules. The compilation is done by writing the rules, without having to specify each compilation option manually. (I don't know how to makefile, so here's a brief introduction.) When you're done writing a makefile, you just need to run themakecommand, the makefile is automatically compiled according to the rules to generate the corresponding executable file. Note thatmakeThe command is followed by the path to the makefile.

cmake vs.

For some complex projects, makefile rules can be troublesome to write, hence the emergence of cmake. cmake is a cross-platform compilation tool that can be used to manage project builds, and by writing cmake, you can automatically generate the corresponding makefile, and then run themakecommand compiles and generates an executable file.

The cmake configuration file is, which is the core configuration file of cmake, mainly used to define the project's source files, header files, libraries and other information, as well as compilation options and so on.

simplestBelow:

cmake_minimum_required(VERSION 3.6)
# Specify the minimum version of cmake required for the project.
project(hello)
# Specify the project name
add_executable(hello )
# Add the executable hello and specify the source file as

When you're done, run in the terminalcmake.command, cmake will automatically generate the corresponding makefile, and then run themakecommand compiles and generates executables. However, there are many configuration files when generating them, so it is customary to create a file namedbuildfolder, and then runcmake..command, the generated makefile is located in thebuildfolder, then runmakecommand compiles and generates an executable file.

For more information about the use of cmake, please refer to the following link.

Simple use of cmake

Install the opencv library and use

The so-called libraries provide us with header files as well as some pre-compiled binaries that we can install to use some of the functionality.

Compile and install opencv

Here we use to download the source code to compile and install the way to install opencv. the so-called installation, in fact, is to compile the code written by others as a library, and then header files and compiled library files copied to the system in the specified directory, but also comes with some instructions to facilitate the compilation of the header files and library files to find.

Source code download link [/opencv/opencv/releases]

Installation tutorial reference:
[/weixin_44796670/article/details/115900538]

Using opencv

consultationSimple use of cmakelatter part
Here is a simple demo to test if the installation is successful:

#include <iostream>
#include <opencv2/>;
using namespace cv.

int main()
{
    Mat src = Mat::zeros(500, 500, CV_8UC3); // create a 500x500 blank image
    circle(src, Point(250, 250), 50, Scalar(255, 255, 255), -1); // draw a white circle in the image
    imshow("src", src); // show the image
    waitKey(0); // wait for the key to be pressed
}

The run should result in a white circle on a black image.
image