Makefile:make install的实现(十一)

news2025/1/12 10:12:25
1、make install的概念
  • 在Linux环境下有些时候软件或者服务会通过源码安装,执行一些make、make install、make clean的指令。例如:redis

    • make:编译所有的文件、生成一些动态库、静态库、可执行程序等等
    • make install:通常会创建一个文件目录,然后写入一些服务的启动停止脚本
    • make clean:清除该项目所有的编译和一些包,重置
  • 这其实就是源码包里面有Makefile,通过makefile编译然后执行安装

  • 流程:

    • 将源文件编译成二进制可执行文件(包括各种库文件)
    • 创建目录,将可执行文件拷贝到指定的目录(安装目录)
    • 加全局可执行的路径
    • 加全局的启停脚本
    • 重置编译环境,删除无关文件
2、实现

假设当前项目比较简单,只有几个文件

  • 08_main.cpp:主程序文件
  • Makefile文件
  • 但是最后需要再当前目录下生成一个tmp文件,里面需要有:
    • 08_main:二进制可执行文件
    • 08_main.log:程序运行时的一些输出日志写入到里面
    • 08_main_start:全局启动脚本(需要软连接或拷贝到/usrl/local/bin下)
    • 08_main_stop:全局停止脚本(需要软连接或拷贝到/usrl/local/bin下)
  • 最终目标图如下

在这里插入图片描述

2.1、main.cpp
#include <iostream>
#include <unistd.h>

int main()
{

    for(int i = 1; i ;i++){
        std::cout << "08_main_running-" << i << std::endl;
        sleep(1);
    }
    return 0;
}
2.2、Makefile
  • 变量:

    • src:先获取到当前路径下的所有.cpp文件

    • target:可执行目标文件名

      • install_path:需要创建的文件夹,文件夹下需要有
        • 08_main、08_main.log、08_main_start、08_main_stop四个文件
    • start_sh:启动脚本名称

    • stop_sh:停止脚本名称

    • log:日志文件名

  • 命令:

    • $(target):$(src):生成可执行目标,这里的可执行目标比较简单,这也是第一个目标,也就是make默认执行的入口

      • g++ $< -o $@:编译生成可执行目标08_main
    • install:$(target):这就是make install所执行的目标,这里调用了一些shell编程脚本的东西

      • if [ -d $(install_path) ];\:首先判断当前文件是否存在:如果存在输出一些提示then echo $(install_path) exist; \

      • else:否则就开始进行文件的一些操作和连接

        • ·mkdir $(install_path);\:当前目录创建下tmp文件夹

        • mv $(target) $(install_path);\:将生成的可执行文件移入到tmp文件夹下

        • touch $(install_path)$(log);\:在tmp文件夹下创建一个运行产生的日志文件

        • sudo ln -s $(absolute_path)$(install_path)$(target) $(ln_path);\:软连接这个可执行程序到/usr/local/bin下,使得全局都可以执行

        • echo "$(absolute_path)$(install_path)$(target)>$(absolute_path)$(install_path)$(log) & echo $(target) running">$(install_path)$(start_sh);\:这个脚本的意思是将可执行文件的执行指令写入到08_main_start启动脚本中,并且把输出结果重定向到08_main.log日志文件中,并且在后台运行(不占用bash),在输出一些提示。

          /home/splay/Makefile/08-make-install/./tmp/08_main>/home/splay/Makefile/08-make-install/./tmp/08_main.log & echo 08_main running
          
        • echo "killall $(absolute_path)$(install_path)$(target)">$(install_path)$(stop_sh);\:将停止脚本写入到08_main_stop脚本中

          killall /home/splay/Makefile/08-make-install/./tmp/08_main
          
        • sudo chmod a+rwx $(install_path)$(start_sh);\:给08_main_start脚本加入读写执行权限,下同

        • sudo ln -s $(absolute_path)$(install_path)$(start_sh) $(ln_path);\:将08_main_start启动脚本软连接到/usr/local/bin下,使得可以全局执行,下同。软连接需要注意使用绝对路径,使用相对路径会导致错误,正确的软连接是淡绿色,错误的软连接是红色

    • make clean:这是make clean的执行目标,主要就是清除上面生成的这些文件和软链接的环境变量

    • .PHONY: clean install:伪目标

src=$(wildcard ./*.cpp)
target:=08_main


install_path:=./tmp/
ln_path:=/usr/local/bin/
start_sh:=$(target)_start
stop_sh:=$(target)_stop
log:=$(target).log

absolute_path:=$(shell pwd)/


$(target):$(src)
	g++ $< -o $@

install:$(target)
	if [ -d $(install_path) ];\
		then echo $(install_path) exist; \
	else \
	  	mkdir $(install_path);\
	  	mv $(target) $(install_path);\
	  	touch $(install_path)$(log);\
  		sudo ln -s $(absolute_path)$(install_path)$(target) $(ln_path);\
  		echo "$(absolute_path)$(install_path)$(target)>$(absolute_path)$(install_path)$(log) & echo $(target) running">$(install_path)$(start_sh);\
  		echo "killall $(absolute_path)$(install_path)$(target)">$(install_path)$(stop_sh);\
  		sudo chmod a+rwx $(install_path)$(start_sh);\
  		sudo chmod a+rwx $(install_path)$(stop_sh);\
  		sudo ln -s $(absolute_path)$(install_path)$(start_sh) $(ln_path);\
  		sudo ln -s $(absolute_path)$(install_path)$(stop_sh) $(ln_path);\
  	fi;

clean:
	$(RM) $(target)
	$(RM) -rf $(install_path)
	sudo $(RM) -r $(ln_path)$(target)
	sudo $(RM) -r $(ln_path)$(start_sh)
	sudo $(RM) -r $(ln_path)$(stop_sh)


.PHONY: clean install

在这里插入图片描述

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

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

相关文章

Qt | Qt 框架结构概述

一、Qt 基本框架概述 1、Qt 5 引入了模块化的概念,Qt 5 将实现众多功能的 Qt 库细分为各个模块,也就是说一个模块中包含了实现某种功能的众多 C++类库,比如 Qt GUI 模块用于图形用户界面绘制,该模块中包含了实现 GUI 组件的类库,比如 QFont、QImage、QOpenGL、QWindow 等…

11.python的字典dict(下) 遍历字典,结构优化

11.python的字典dict(下) 遍历所有的键值对 items()方法是字典的一个内置方法&#xff0c;用于返回字典中所有键值对的视图&#xff08;view&#xff09;。它返回一个可迭代的对象&#xff0c;每个元素都是一个包含键和对应值的元组。 下面用一个例子来说明items()方法的用法…

闻风丧胆的算法(二)

&#x1f308;个人主页&#xff1a;Rookie Maker &#x1f525; 系列专栏&#xff1a;算法 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于IT的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎来到小田代码世界~ &#x1f601; 喜欢的小…

第十二届通信和宽带网络国际会议(ICCBN 2024)即将召开!

2024年第十二届通信和宽带网络国际会议将于2024年7月25日至27日在西藏林芝举行会议涵盖的议题广泛多样&#xff0c;包括但不限于&#xff1a;5G、6G技术与应用&#xff0c;宽带网络架构和优化&#xff0c;物联网与智能连接&#xff0c;人工智能在通信领域的应用&#xff0c;数据…

C++ 标准库类型stackqueue

C/C总述&#xff1a;Study C/C-CSDN博客 栈与队列详解&#xff08;数据结构&#xff09;&#xff1a;栈与队列_禊月初三-CSDN博客 stack&#xff08;栈&#xff09; stack的常用函数 函数说明功能说明stack()构造空栈push(T& val)将元素val压入栈中size()返回栈中元素个…

蓝桥杯算法题:区间移位

题目描述 数轴上有n个闭区间&#xff1a;D1,...,Dn。 其中区间Di用一对整数[ai, bi]来描述&#xff0c;满足ai < bi。 已知这些区间的长度之和至少有10000。 所以&#xff0c;通过适当的移动这些区间&#xff0c;你总可以使得他们的“并”覆盖[0, 10000]——也就是说[0, 100…

【数据结构(一)】初识数据结构

❣博主主页: 33的博客❣ ▶文章专栏分类: Java从入门到精通◀ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你学更多数据结构知识 目录 1.前言2.集合架构3.时间和空间复杂度3.1算法效率3.2时间复杂度3.2.1大O的渐进…

Unity类银河恶魔城学习记录12-4 p126 Item Tooltip源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili UI.cs using System.Collections; using System.Collections.Generic; usi…

AD20全流程的使用笔记

目录 首先一个完整的AD工程文件需要我们自己建立的文件有这些&#xff1a; 新建工程&#xff1a; 从现有的工程文件中将元件添加到原理图库&#xff1a; 元件的摆放&#xff1a; 器件的复制及对齐&#xff1a; 导线、Netlabe、端口的添加&#xff1a; Value值的校对&…

每日一练 寻找两个正序数组的中间数

题目参上&#xff0c;以下是解题思路&#xff1a; 首先&#xff0c;我们应该想到的一种方法是把两数组合并为一个整体的数组&#xff0c;然后返回其中位数即可。那么我们如何合并两数组呢&#xff1f;我们可以用归并排序&#xff0c;设置上下两指针&#xff0c;不断遍历返回较…

idea Springboot校园新闻系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 校园新闻发布系统是一套完善的信息系统&#xff0c;结合springboot框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&a…

LeetCode-217存在重复的元素

217 存在重复的元素 给定一个整数数组&#xff0c;判断是否存在重复元素。 如果存在一值在数组中出现至少两次&#xff0c;函数返回 true 。如果数组中每个元素都不相同&#xff0c;则返回 false 。 JavaScript的 Array 对象是用于构造数组的全局对象&#xff0c;数组是类似…

如何在iPhone上恢复永久删除的照片?

2007 年&#xff0c;Apple Inc. 推出了这款震撼人心的智能手机&#xff0c;后来被称为 iPhone。您会惊讶地发现&#xff0c;迄今为止&#xff0c;Apple Inc. 已售罄 7 亿台 iPhone 设备。根据 2023 年 8 月的一项调查数据&#xff0c;95% 的智能手机利润都落入了苹果公司的口袋…

【Vue】watch监听复杂数据,新值与旧值一样

问题 watch监听复杂数据&#xff0c;例如数组&#xff0c;旧值与新值一样 解决方案 监听回调里返回新数组&#xff0c;新、旧数组地址改变&#xff0c;得到的值也就不一样&#xff0c;例↓ ()>[...data] 码 test.js // 数据 const musicList ref([{ id: 540000200805…

兑换码生成算法

兑换码生成算法 兑换码生成算法1.兑换码的需求2.算法分析2.重兑校验算法3.防刷校验算法 3.算法实现 兑换码生成算法 兑换码生成通常涉及在特定场景下为用户提供特定产品或服务的权益或礼品&#xff0c;典型的应用场景包括优惠券、礼品卡、会员权益等。 1.兑换码的需求 要求如…

软考--软件设计师(软件工程总结2)

目录 1.测试方法 2.软件项目管理 3.软件容错技术 4.软件复杂性度量 5.结构化分析方法&#xff08;一种面向数据流的开发方法&#xff09; 6.数据流图 1.测试方法 软件测试&#xff1a;静态测试&#xff08;被测程序采用人工检测&#xff0c;计算机辅助静态分析的手段&…

MyBatis 解决上篇的参数绑定问题以及XML方式交互

前言 上文:MyBatis 初识简单操作-CSDN博客 上篇文章我们谈到的Spring中如何使用注解对Mysql进行交互 但是我们发现我们返回出来的数据明显有问题 我们发现后面三个字段的信息明显没有展示出来 下面我们来谈谈解决方案 解决方案 这里的原因本质上是因为mysql中和对象中的字段属性…

构建未来交通:香橙派OPI Airpro上的智能交通监管系统

引言&#xff1a; 随着城市化进程的加速&#xff0c;交通管理变得越来越复杂。 传统的交通监管系统往往无法有效应对日益增长的车辆数量和复杂的交通状况。因此&#xff0c;我们需要一种更加智能和自适应的解决方案来提高交通效率并减少事故发生率。 香橙派OPI Airpro以其强大的…

07 - D触发器

---- 整理自B站UP主 踌躇月光 的视频 1. 电路实现 将 D 接到 S 端&#xff0c;D 取反接到 R 端&#xff0c;两个输入合成一个输入&#xff0c;R 和 S 总是相反的&#xff0c;就构成了 D 触发器。再添加一个EN&#xff0c;作为锁存功能&#xff0c;EN0 时&#xff0c;R 和 S 都…

Mac删除软件,动一动手指,几秒就彻底删除 mac删除软件删不掉的解决方法 mac删除软件后怎么删除软件数据

当你入职新公司&#xff0c;接手前任员工使用的Mac电脑时&#xff0c;很可能会遇到一个非常普遍的问题&#xff1a;电脑中装有大量你不需要的软件。这些软件不仅占用宝贵的硬盘空间&#xff0c;还可能影响电脑的运行速度和效率。为了获得一个干净、清爽的使用体验&#xff0c;删…