Makefile学习:第一章 GCC的简易用法

参考:《鸟哥的LINUX私房菜》

一、编译与链接

        假设我们先在linux的控制台界面中使用 nano hello.c ,进入文件后写一个简单的程序。现在要用GCC来编译运行,我们有两种方式:

// hello.c
#include <stdio.h>int main() {printf("Hello, World!\n");return 0;
}

 1.1 分布编译链接:

gcc -c hello.c     # 仅预处理、编译gcc -o hello hello.o    # 仅链接# -o hello 指定输出的可执行文件名为hello
# 后面的 hello.o 是要链接的目标文件

  gcc -c hello.c这个命令告诉GCC仅进行预处理、编译(将C代码转换为汇编代码,再转换为目标代码)步骤,但不进行链接,最终生成一个 目标文件(.o文件)-c选项表示编译并停止,不链接。

        通过先gcc -c hello.c生成目标文件,然后再gcc -o hello hello.o进行链接,这种方式在大型项目中更为常见,尤其是在需要对多个源文件进行单独编译,最后统一链接的场景。这样做的好处是可以分开编译阶段和链接阶段,提高编译效率,特别是在修改了项目中的一部分代码时,只需要重新编译修改过的文件,而不是整个项目。

1.2 直接编译链接:

gcc -o hello hello.c

        直接使用gcc -o hello hello.c时,GCC完成了整个过程——预处理、编译、汇编、以及链接。它从源代码开始,直接产生一个可执行文件。这种方式适合于简单的项目或一次性编译的情况。

 1.3 最后运行可执行文件 ./hello

1.4 问题:为什么我们要制作出目标文件?

比如现在我们有一个 hello.c 主程序和 thanks.c 子程序:

hello.c (主程序)#include <stdio.h>int main() {printf("Hello, World!\n");thank();return 0;
}
thanks.c (子程序)#include <stdio.h>void thank(void) {printf("Thank you\n");
}

先对 hello.c 和 thanks.c 编译,再将 hello.o 和 thanks.o 链接到可执行文件 hello

        由于我们的源代码文件有时并非仅只有一个文件,所以我们无法直接进行编译。这个时候就需要先产生目标文件,然后再以链接制作成为二进制可执行文件。

        另外,假设我们更新了 thanks.c 文件的内容,那只要重新编译 thanks.c 来产生新的 thanks.o ,然后再以链接制作出新的二进制可执行文件即可,而不需要重新编译其他没有修改过的源代码文件。当我们实际在企业开发的时候,往往一个工程的代码量很大,如果将源代码全部编译则要消耗大量的时间,甚至性能不好的电脑或出现卡死的现象。

二、调用外部函数库:加入链接的函数库 

hello.c (主程序不变,但我们将调用thanks.c中的新功能)

#include <stdio.h>// 如果在hello.c中直接调用了calculate_sine,则需要声明extern double calculate_sine(double angle_degrees);int main() {printf("Hello, World!\n");double angle_in_degrees = 45.0;double sine_value = calculate_sine(angle_in_degrees);printf("The sine of %.2f degrees is: %.4f\n", angle_in_degrees, sine_value);return 0;
}

thanks.c (添加计算正弦值的功能,使用math.h库)

#include <stdio.h>
#include <math.h> // 包含数学函数库double calculate_sine(double angle_degrees) {double angle_radians = angle_degrees * M_PI / 180.0; // 将角度转换为弧度return sin(angle_radians); // 使用sin()函数计算正弦值
}

假设我们和刚刚一样的步骤: 

 正确步骤:

2.1 函数库的链接(库文件位于标准路径) 一般情况

gcc -c hello.c thanks.c
gcc hello.o thanks.o -lm -o hello

         [-lm] 这是一个链接选项,告诉GCC在链接过程中链接数学库(Math Library)。这里的-l是一个通用的选项,用于指定要链接的库名,而紧跟其后的m指定了具体的库名。这里的m代表数学库(libm的缩写),它是标准C库的一部分,提供了许多数学相关的函数,比如sin(), cos(), sqrt()等。当编译器遇到代码中调用了这些函数时,就需要通过-lm来确保对应的库被链接进来,以便在运行时能够找到这些函数的实现。

        当你在GCC命令行中使用-lm标志时,实际上是在告诉编译器的链接阶段需要链接标准数学库。这个库可能以动态库(如libm.so静态库(如libm.a的形式存在。动态库在程序运行时被加载,而静态库则在编译时被直接嵌入到可执行文件中。在大多数Linux系统中,如果不特别指定,GCC通常会优先寻找动态库。

2.2 函数库的链接(库文件位于非标准路径)

        如果您的库文件位于非标准路径,比如一个特定的liblib64目录下,您需要使用-L选项来指定额外的库搜索路径,紧接着使用-l指定库名。例如,如果有一个库文件libcustom.so位于/path/to/my/libs/lib64目录下,您可以这样编译:

gcc hello.o thanks.o -L/path/to/my/libs/lib64 -lcustom -lm -o hello
  • -L/path/to/my/libs/lib64告诉GCC在指定的目录中查找库文件。
  • -lcustom指示链接器链接名为libcustom.solibcustom.a的库。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3245784.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

PostgreSQL 中如何解决因大量并发删除和插入操作导致的索引抖动?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何解决因大量并发删除和插入操作导致的索引抖动一、理解索引抖动二、索引抖动的影响三…

抖音短视频seo矩阵系统源码(搭建技术开发分享)

#抖音矩阵系统源码开发 #短视频矩阵系统源码开发 #短视频seo源码开发 一、 抖音短视频seo矩阵系统源码开发&#xff0c;需要掌握以下技术&#xff1a; 网络编程&#xff1a;能够使用Python、Java或其他编程语言进行网络编程&#xff0c;比如使用爬虫技术从抖音平台获取数据。…

玩转HarmonyOS NEXT之AppStorage应用全局UI状态存储

概述 AppStorage是应用全局的UI状态存储&#xff0c;是和应用的进程绑定的&#xff0c;由UI框架在应用程序启动时创建&#xff0c;为应用程序UI状态属性提供中央存储。 AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储&#xff0c;这…

LeetCode热题100刷题16:74. 搜索二维矩阵、33. 搜索旋转排序数组、153. 寻找旋转排序数组中的最小值、98. 验证二叉搜索树

74. 搜索二维矩阵 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int row matrix.size();int col matrix[0].size();for(int i0;i<row;i) {//先排除一下不存在的情况if(i>0&&matrix[i][0]>target…

redis安装,启动客户端、验证(redis第一次作业)

Redis简介 全称&#xff1a; mote ctionary erver &#xff08;远程字典服务器&#xff09;。是完全开源免费的&#xff0c;用 C 语言编写的&#xff0c;遵守 BSD协议。是一个高性能的 (key/value) 分布式内存数据库&#xff0c;基于内存运行并支持持久化的 NoSQL 数据库&#…

在 Windows 上开发.NET MAUI 应用_1.安装开发环境

开发跨平台的本机 .NET Multi-platform App UI (.NET MAUI) 应用需要 Visual Studio 2022 17.8 或更高版本&#xff0c;或者具有 .NET MAUI 扩展的最新 Visual Studio Code。要开始在 Windows 上开发本机跨平台 .NET MAUI 应用&#xff0c;请按照安装步骤安装 Visual Studio 20…

Java面试题--JVM大厂篇之深入解析JVM中的Serial GC:工作原理与代际区别

目录 引言&#xff1a; 正文&#xff1a; 一、Serial GC工作原理 年轻代垃圾回收&#xff08;Minor GC&#xff09;&#xff1a; 老年代垃圾回收&#xff08;Major GC或Full GC&#xff09;&#xff1a; 二、年轻代和老年代的区别 年轻代&#xff08;Young Generation&a…

【简历】郑州某二本学院:前端秋招简历指导,简历通过率接近于0

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一份二本前端同学的校招简历。25届的二本同学求职方向主要是在小公司&#xff0c;但是这个同学他故意把学校放在简历最后&#xff0…

橙芯创想:香橙派AIPRO解锁升腾LLM与Stable Diffusion的创意密码

文章目录 引言 一. 香橙派AI PRO配置以及展示优秀的扩展能力实物展示 二、Ascend-LLM模型部署开机xshell连接香橙派实战运行部署 三、Stable Diffusion介绍sd模型&#xff0c;vae&#xff0c;lora模型进入应用文生图工作区调参区图生图 四、体验总结总结性能噪音便捷性 引言 在…

linux的学习(七):读取,函数,正则表达式,文本处理工具cut和awk

##简介 shell编程中的读取&#xff0c;函数&#xff0c;正则表达式&#xff0c;文本处理工具的简单使用 read read&#xff1a;读取控制台的输入 参数&#xff1a; -p&#xff1a;指定读取时的提示符-t&#xff1a;等待读取的时间 脚本例子 编写i.sh脚本&#xff0c;enter…

C++基础知识:C++内存分区模型,全局变量和静态变量以及常量,常量区,字符串常量和其他常量,栈区,堆区,代码区和全局区

1.C内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区:存放函数体的二进制代码&#xff0c;由操作系统进行管理的&#xff08;在编译器中所书写的代码都会存放在这个空间。&#xff09; 全局区:存放全局变量和静态变量以及常量 栈区:由编译器自动分…

数学基础【俗说矩阵】:齐次线性方程和非齐次线性方程求解-学习笔记

一、矩阵基础知识 二元一次方程的传统解法 不论是代入消元法还是加减消元法都统称 【高斯消元法】。 齐次方程组和非齐次方程组 线性方程组的解 线性方程的向量展示 向量规则 矩阵的高斯消元和初等行变行及其规则 高斯消元规则 初等行变换 矩阵经初等行变换成阶梯矩阵&…

【Linux】线程——线程互斥的概念、锁的概念、互斥锁的使用、死锁、可重入和线程安全、线程同步、条件变量的概念和使用

文章目录 Linux线程4. 线程互斥4.1 线程互斥的概念4.2 锁的概念4.2.1 互斥锁的概念4.2.2 互斥锁的使用4.2.3 死锁4.2.4 可重入和线程安全 5. 线程同步5.1 条件变量的概念5.2 条件变量的使用 Linux线程 4. 线程互斥 我们之前使用了线程函数实现了多线程的简单计算模拟器。 可以…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【26】【内网穿透】cpolar

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【27】【内网穿透】cpolar 内网穿透cpolar内网穿透联调配置练习—使用公网地址访问gulimall.com参考 内网穿透 正常的外网需要访问我们项目的流程是&#xff1a; 买服务器并且有公网固定…

【数据结构】深入理解Floyd最短路径算法:全面解析及Python实现

文章目录 一、Floyd-Warshall算法简介二、Floyd-Warshall算法的数学表述三、Floyd-Warshall算法的Python实现四、Floyd-Warshall算法的应用场景五、Floyd-Warshall算法的优缺点六、优化与改进七、总结 Floyd-Warshall算法是一种用于解决加权图中最短路径问题的经典算法。该算法…

基于Ubuntu2310搭建openstack高可用集群B版

openstack-ha 环境初始化安装haproxy安装keepalived数据库集群高可用rabbitmq集群高可用memcache集群配置 keystone高可用glance高可用placement高可用nova高可用neutron高可用horizon高可用 本实验使用两台节点master和node配置haproxy高可用&#xff0c;keepliaved配置主备抢…

极验设备指纹HarmonyOS 鸿蒙版SDK官方下载

近日&#xff0c;华为开发者大会&#xff08;HDC 2024&#xff09;在东莞召开。在大会开幕日的首场主题演讲中&#xff0c;华为宣布当前已有TOP5000应用成为鸿蒙原生应用&#xff0c;350&#xff0b;SDK已适配HarmonyOS NEXT版本。其中&#xff0c;极验作为其重要伙伴&#xff…

JWT令牌详细解析

JWT令牌 前言一、JWT是什么&#xff1f;二、JWT与传统CookieSession的对比三、JWT1. JWT的功能2. JWT的结构3. JWT的使用 前言 主要介绍了SpringBoot集成JWT令牌详细说明,JWT方式校验方式更加简单便捷化&#xff0c;无需通过redis缓存&#xff0c;而是直接根据token取出保存的…

解决C#读取US7ASCII字符集oracle数据库的中文乱码

&#x1f468; 作者简介&#xff1a;大家好&#xff0c;我是Taro&#xff0c;全栈领域创作者 ✒️ 个人主页&#xff1a;唐璜Taro &#x1f680; 支持我&#xff1a;点赞&#x1f44d;&#x1f4dd; 评论 ⭐️收藏 文章目录 前言一、解决方法二、安装System.Data.OleDb连接库三…

隐藏需求缺失的4种解决技巧

在需求分析过程中&#xff0c;隐藏需求的缺失往往会造成项目范围扩张、成本增加&#xff0c;造成延期交付和风险增加等问题&#xff0c;直接影响客户满意度。而隐藏需求的挖掘和确认&#xff0c;有利于优化项目范围&#xff0c;提升产品质量&#xff0c;增强团队信心。 因此&am…