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四个文件
- install_path:需要创建的文件夹,文件夹下需要有
-
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_maininstall_path:=./tmp/
ln_path:=/usr/local/bin/
start_sh:=$(target)_start
stop_sh:=$(target)_stop
log:=$(target).logabsolute_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