从零学习GCC,Makefile,CMakeList编译

近期想系统地学习一下C++软件开发,因此记录一下自己的学习笔记,方便复习。大多数内容都是整理搬运别的博主文章内容,加上自己的理解归纳。如果大家想了解更深的内容或者有不明白的地方,可以阅读参考中记录的博客。
平台:Windows10+mingw

参考

【1】Linux编译工具:gcc入门
【2】Linux下gcc生成和使用静态库和动态库详解
【3】一个简单的make&makefile编写指南
【4】Make 编译脚本上手
【5】CMake入门实践

准备

假设我们工程里有三个文件

  1. main.c
#include <stdio.h>
#include <fun.h>

int main(){
    printf("this is main\n");
    fun();
    return 0;
}
  1. fun.c
#include <stdio.h>
#include <fun.h>

void fun(){
    printf("This is fun!\n");
    return;
}
  1. fun.h
#ifndef MAIN_FUN_H
#define MAIN_FUN_H
void fun(void);
#endif

我们要如何编译这个工程呢?

GCC编译

– gcc简介

gcc的全称是GNU Compiler Collection,它是一个能够编译多种语言的编译器。最开始gcc是作为C语言的编译器(GNU C Compiler),现在除了c语言,还支持C++、java、Pascal等语言。gcc支持多种硬件平台。

– gcc编译过程

gcc编译程序主要经过四个过程:

  • 预处理(Pre-Processing)
  • 编译 (Compiling)
  • 汇编 (Assembling)
  • 链接 (Linking)

    预处理实际上是将头文件、宏进行展开。编译阶段,gcc调用不同语言的编译器,例如c语言调用编译器ccl。gcc实际上是个工具链,在编译程序的过程中调用不同的工具。汇编阶段,gcc调用汇编器进行汇编。链接过程会将程序所需要的目标文件进行链接成可执行文件。汇编器生成的是可重定位的目标文件,学过操作系统,我们知道,在源程序中地址是从0开始的,这是一个相对地址,而程序真正在内存中运行时的地址肯定不是从0开始的,而且在编写源代码的时候也不能知道程序的绝对地址,所以重定位能够将源代码的代码、变量等定位为内存具体地址。下面以一张图来表示这个过程,注意过程中文件的后缀变化,编译选项和这些后缀有关。

– gcc编译实例

编译单文件
gcc -c main.c / gcc -o main main.c
区别是前者生成main.o,还需要链接到exe文件,后者会直接生成main.exe
注意1:有一些博主写的是gcc -c main.c -o main,但我发现这样很容易报错,错误原因未知,也许跟系统有关。所以Windows下还是建议最好-o在前。我这里就都写成-o在前了。
注意2:我使用gcc -o main -c main.c编译时无法生成o文件或exe文件,会生成一个没有后缀的文件。使用gcc -o main.o -c main.c是可以的,但使用gcc -o main.exe -c main.c不行。看来-c, -o同时使用只支持生成o文件,而且只支持编译一个文件。好奇怪…

或者一步步进行

1 gcc -o main.i  -E main.c     #对main.c文件进行预处理,生成预处理文件
2 gcc -o main.s -S main.i     #对预处理文件进行编译,生成了汇编文件
3 gcc -o main.o -c main.s   #对汇编文件进行编译,生成了目标文件
4 gcc -o main main.o          #对目标文件进行链接,生成可执行文件

使用gcc时可以加上-Wall选项,否则编译器不会报出警告
gcc -Wall -o bad bad.c

编译多文件
gcc -o main fun1.c fun2.c #生成可

CMakeLists.txt文件中,通过target_link_libraries命令可以将可执行程序链接到库函数上。例如,在给定的例子中,通过target_link_libraries(helloslam hello)将可执行程序helloslam链接到了名为hello的库函数上。这样在编译和运行程序时,程序就可以使用库函数中定义的功能了。123 #### 引用[.reference_title] - *1* [CMake生成并使用库函数](https://blog.youkuaiyun.com/qq_41889538/article/details/127101156)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *2* [从学习GCC,Makefile,CMakeList编译](https://blog.youkuaiyun.com/amateur_/article/details/113780562)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *3* [【cmake开发(1)】C代码编译过程,cmakelist基础步骤](https://blog.youkuaiyun.com/djfjkj52/article/details/106613745)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值