Liunx下源代码安装&&make&&makefile

2023-05-16

Linux下安装软件的方式分为源代码安装和二进制安装

  • 源代码安装,即使用应用程序源代码进行编译安装
  • 二进制安装,例如red hat发行的 .rpm包、debian发行的 .deb包

源代码安装

用c语言为例

#include <stdio.h>

int main(){
	printf("hello world");
	return 1;
}

使用gcc进行编译。 gcc a.c 然后当前目录会生成一个a.out 文件 然 ./a.out就执行了 输出 hello world

上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编 (Assembly)和连接(Linking)。

  • gcc最开始是c语言的编译器,后来随着发展已经支持很多种语言了。
  • gcc -E 预处理 gcc -E a.c -o a.i 将预处理命令行输出到 a.i文件
  • gcc -S a.i -o a.s -S 指令是将预编译的指令变成汇编代码。
  • gcc -c test.s -o test.o -c操作将其编译成目标文件,gas汇编器负责将其编译为目标文件
  • gcc test.o -o test 连接负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。附加的目标文件包括静态连接库和动态连接库。

源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。以上操作gcc a.h就完成了。

对于源代码安装以nginx为例

1.wget http://nginx.org/download/nginx-1.18.0.tar.gz
2.tar -zxvf nginx-1.18.0.tar.gz
#然后看下configure文件,一般这个文件就是这个包的安装脚本(也可以叫别的名)
3.vim  configure  看下发现 原来是shell脚本  #!/bin/sh
一般情况下 --prefix=/usr/local/nginx  其实就是指定安装路径。./configure --help  看具体参数
4. ./configure --prefix=/home/zhangyong/nginx --without-http_rewrite_module --without-http_gzip_module
configure会生成一个makefile文件    (#只是测试具体--参数有待补充)
makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
5.make    #make命令是一个解释Makefile中指令的命令工具。  编译源代码
6.make install #make install是用来安装的(具体以makefile写的为准),它也从Makefile中读取指令,安装到指定的位置。  

关于configure执行完会生成 objs目录和 Makefile文件。环境检测、参数解析、目录生成、Makefile文件的生成等。 objs文件内容如下:

  • src目录存放编译时产生的目标文件
  • ngx_modules.c是一个很重要的文件,是用来定义ngx_modules数组的。这个数组用于指明每个模块在nginx中的优先级,越靠前优先级越高,当一个请求同时符合多个模块的处理规则的时候,就按照ngx_modules数组的顺序来选择最靠前的一个。所以说,ngx_modules数组的先后顺序很重要,不正确的顺序会导致nginx错误。
  • autoconf.err保存的是configure的执行结果。
  • Makefile文件用于编译nginx工程以及在加入install参数后安装nginx

make

代码变成可执行文件,叫做编译(compile);先编译这个,还是先编译那个(即编译的安排),叫做构建(build),make是最常用的构建工具。make是一个命令工具,是一个解释makefile中指令的命令工具。make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译。主要是编写Makefile文件

Makefile

makefile的格式如下

<target> : <prerequisites> 
[tab]  <commands>

上面第一行冒号前面的部分,叫做"目标"(target),冒号后面的部分叫做"前置条件"(prerequisites);第二行必须由一个tab键起首,后面跟着"命令"(commands)。

"目标"是必需的,不可省略;"前置条件"和"命令"都是可选的,但是两者之中必须至少存在一个。下面是demo 可以 make targets 运行看结果

  • .PHONY是指定后面的为伪目标,不然如果有同名文件该不识别命令了。
  • 前置条件的多个target之间空格,命令前面tab键(如果想用其他代替tab符,.RECIPEPREFIX = > 指定>为[tab])、 前置条件就是一个beforeAction
  • 命令中每个shell命令是独立存在的,make test 不会输出环境变量zy 但是加上 ; \ 就可以了 make test-dev \是换行主要 ; 分号起作用
  • make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。
.PHONY: build package
default:							#如果没指定target, make  就走第一个target
        echo "if nothing do default"

build:
        echo "this is build"

package: default build
        echo "this is package"
test:
        export zy=zhangyong
        echo "$$zy"					
test-dev:
        export zy=zhang; \
        echo "$$zy"			       # $$引用环境变量
test-echo:
        @echo "this is echoing"    #@符号是不打印这个命令,默认make会将这行命令打印出来。
var1=123
var2=$(var1)
var3:=$(var1)123  # :=是扩展变量,此时下面那个var1 赋值不会被引用
var6:=$(var1)
var4=666
var4?=$(var1)     # ?=如果变量之前定义过,则不执行当前赋值
var5=777
var5+=$(var1)     # +=追加
var1=444
tvar:
        echo "$(var1) $(var2) $(var3) $(var6) $(var4) $(var5)"
foo=a.java b.java c.java
bar=$(foo:%.java=%.class)         #字符串替换
tget:
        echo "$(foo)    $(bar)"
tspecial:tget tvar
        echo "第一个依赖对象$<"; echo "目标$@"; echo "所有依赖对象$^";
        
asd=100
ifeq ($(asd),100)          		  #判断变量asd是否等于100    ifeq (<arg1>, <arg2>)   还有ifneq  如果不等
        dd="asd100"
else
        dd="hello"
endif
ifdef var1					   	  #判断是否为空   还有 ifndef <variable-name>
        ss="123"
endif
tif:
        echo "$(dd)"
goal:
        echo "$(MAKECMDGOALS)"          #输出当前执行的命令的target  make goal ===> goal
tdir:
        -mkdir dir                      # - 忽略错误
%.o: %.c
        @#外面执行make $(ls *.c |sed 's/c/o/g ') 来进行模式规则执行,将所有.c通过command编译成.o
        $(CC) $(CFLAGS) $< -c
wild:
ifneq ($(wildcard *.c),)                #wildcard列出匹配的文件/目录 当前demo测试是否为空
        echo $(wildcard *.c)
else
        -mkdir nodir
endif

关于函数

a=a.java b.java
b=$(subst v,m, $(a))                    #$(subst <from>,<to>,<text>)
c=$(patsubst %.java,%.net,$(a))         #$(patsubst <pattern>,<replacement>,<text>)
d=$(strip " s1s2s " )                   #$(strip <string>) 去首尾空格
e=$(findstring a,abcda)                 #$(findstring <find>,<in>)查找字符串函数
f=$(filter %.c %.s, a.c b.s c.h d.java) #$(filter <pattern...>,<text>) 以 <pattern> 模式过滤 <text> 字符串中的单词,保留符合模式 <pattern> 的单词。可以有多个模式
g=$(filter-out %.c %.s, a.c b.s c.h d.java) #$(filter-out <pattern...>,<text>) 反过滤函数
h=$(sort b a c)                         #$(sort <list>) 排序
i=$(dir src/a home/b)                   #$(dir <names...>)取目录名
j=$(notdir src/a home/b)                #$(notdir <names...>) 取文件名
k=$(suffix zhang.txt)                   #取後缀函数——suffix。$(suffix <names...>) 可变形参
l=$(basename zhang.txt)                 #取前缀函数——basename。$(basename <names...>)
ttttt=a b c d
m=$(foreach key,$(ttttt),$(key).java)   #$(foreach <var>,<list>,<text>)
n=$(if 1=1,n=1,n=2)
res= $(1)---$(2)
o=$(call res,qq,ww)                     #call函数是唯一一个可以用来创建新的参数化的函数。$(call <expression>,<parm1>,<parm2>,...,<parmn>)
p=$(origin o)                           #origin函数不像其它的函数,他并不操作变量的值,他只是告诉你你的这个变量是哪里来的$(origin <variable>)
q=$(shell echo "hello world")           #shell函数也不像其它的函数。顾名思义,它的参数应该就是操作系统Shell的命令
build:
        @echo "$(b) $(c) $(d) $(e) $(f) $(g) $(h) $(i) $(j) $(k) $(l) $(m) $(n) $(o) $(p) $(q)"
 a.jama b.jama			 a.net b.net		  s1s2s 			 a			 a.c b.s  c.h d.java  a b c				 src/ home/ a b		 .txt			 zhang			 a.java b.java c.java d.java    n=1 qq---ww			 file				 hello world

参考:https://seisman.github.io/how-to-write-makefile/introduction.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Liunx下源代码安装&&make&&makefile 的相关文章

随机推荐

  • DDR协议解析

    DRAM内部分割成多个L Bank xff0c 每个L Bank形状相同 xff0c 彼此独立 xff0c 可以独立工作 早期的DRAM芯片内部分为2个L Bank xff0c 后来是4个 xff0c DDR3内存芯片为8个 在进行寻址时需
  • apt-get安装指定版本&查询版本

    一 通过apt get安装指定版本 apt get install lt lt package name gt gt 61 lt lt version gt gt 二 查询指定软件有多少个版本 说明 xff1a 在Linux用这个查询并不能
  • 使用apt-get install时有时候一堆依赖要安装,一个一个安装特别烦人,可以直接用suggest全部安装,具体命令如下

    使用apt get install时有时候一堆依赖要安装 xff0c 一个一个安装特别烦人 xff0c 可以直接用suggest全部安装 xff0c 具体命令如下 apt get install install suggests packa
  • linux-Centos 7下tftp-server服务的安装与配置

    转自 http www cnblogs com 5201351 p 4934625 html TFTP xff08 Trivial File Transfer Protocol 简单文件传输协议 xff09 是TCP IP协议族中的一个用来
  • Linux启动打印信息

    U Boot 1 1 6 Oct 5 2016 16 45 02 for SMDK6410 u boot 1 1 6 Updated for OK6410 TE6410 Board Version 2012 09 23 OEM Forlin
  • 对比S3C6410外部中断STM32外部中断

    转自 xff1a http comm chinaaet com adi blogdetail aspx id 61 40071 amp currentpage 61 2 a S3C6410外部中断 中断在嵌入式里面是很常见的一个功能了 通过
  • shell脚本记录

    1 find name o 找出当前目录下所有的 o文件 使用在makefile中如下 clean rm f liblog so 96 find name o 96
  • makefile中的patsubst

    1 wildcard 扩展通配符 2 notdir xff1a 去除路径 3 patsubst xff1a 替换通配符 例子 xff1a 建立一个测试目录 xff0c 在测试目录下建立一个名为sub的子目录 mkdir test cd te
  • ElasticSearch学习&&理解

    注 xff1a 本篇的es基于7 5 1版本 目录 Elasticsearch是什么 xff1f ElasticSearch的环境搭建 ElasticSearch的名词 ElasticSearch查询出的数据格式 ElasticSearch
  • Kibana学习&理解

    注 xff1a 本篇的kibana基于7 5 1版本 Kibana是什么 xff1f kibana是一个数据可视化平台 展示与分析 将es里面的东西通过各种图表展示出来 xff0c 还可以执行es的各种搜索 amp 监控 Kibana环境搭
  • filebeat学习

    注 xff1a 本篇基于filebeat7 5 2 filebeat是什么 xff1f Filebeat 是用于转发和集中日志数据的轻量级传送程序 作为服务器上的代理安装 xff0c Filebeat 监视您指定的日志文件或位置 xff0c
  • Git Flow 用法

    git flow 工作流程 如下图所示 master 分支 master 分支主要方稳定 随时可上线的版本 这个分支只能从别的分支上合并过来 xff0c 一般来讲 xff0c 从develop 上合并 xff0c 或者从hotfix分支上合
  • Qt父窗口与子窗口间的焦点传递问题的完美解决

    使用activateWindow 或者raise 参考文章 xff1a https blog csdn net Hoarce article details 107215868 http www manongjc com detail 19
  • Git 工作中的一些命令操作

    本篇为工作中 git 使用过程中的一些操作记载 xff0c 不定期更新 目录 1 git 推本地代码到远程 2 git 放弃修改 commit 撤销远程提交记录 3 git pull push fetch 4 git关联本地与远程分支 5
  • php如何使用S3

    本篇是新手使用PHP调aws的s3服务的一些心得 一 关于AWS S3 s3是一个文件存储服务 xff0c 当需要做成服务来进行微服务调用 xff0c 或者终端服务端文件交流使用s3是一个非常不错的选择 aws各种常见的语言例如 xff1a
  • MySQL相关面试题

    1 MySQL text长度 mysql的text是65535的字节限制 xff0c 而pg是不限制的 2 覆盖索引 聚簇索引 xff08 https blog csdn net alexdamiao article details 519
  • Redis相关面试题

    1 缓存是什么 xff1f 缓存分为本地缓存和分布式缓存 以Java为例 xff0c guava实现的就是本地缓存 xff0c 生命周期随JVM销毁而结束 起多个服务实例 xff0c 就有多份缓存 xff0c 不具有一致性 redis和me
  • 如何断网安装docker

    docker rpm安装 不能联网情况 生产环境可能是不能联网的 xff0c 当我们需要用到docker 或其他组件 的时候 xff0c 就需要借助能联网的环境下载好rpm包 xff0c 然后去操作系统服务器装下载好的docker RPM包
  • docker相关

    优势 xff1a 1 启动快 传统的虚拟机技术启动应用服务往往需要数分钟 xff0c 而 Docker 容器应用 xff0c 由于直接运行于宿主内核 xff0c 无需启动完整的操作系统 xff0c 因此可以做到秒级 甚至毫秒级的启动时间 大
  • Liunx下源代码安装&&make&&makefile

    Linux下安装软件的方式分为源代码安装和二进制安装 源代码安装 xff0c 即使用应用程序源代码进行编译安装二进制安装 xff0c 例如red hat发行的 rpm包 debian发行的 deb包 源代码安装 用c语言为例 include