学习语言最好的途径就是阅读源码,这篇文章通过研究configure文件学习shell
编译开源项目时,一般步骤为
1. ./configure
2. make
3. make install
make就是把项目编译成目标文件。而make install是将编译生成的二进制或者库文件拷贝到系统对应目录下,同时也会拷贝头文件到系统对应目录,以便用户进行二次开发。
但是configure是在干什么呢?进去看下大概能知道是在进行环境检查和配置,包括编译环境和运行环境。但是具体每条命令在干什么?本文通过解读开源项目CAF的configure文件来学习shell语言。
CAF官网:http://actor-framework.org/
源码:https://github.com/actor-framework/actor-framework.git
1. 初探
用vi打开configure文件,前几行如下
#!/bin/sh
# Convenience wrapper for easily viewing/setting options that
# the project's CMake scripts will recognize.
#开头为shell语言的注释,但是第一行很特殊,他告诉系统使用指定的shell解释器执行此文件,这里就是使用/bin/sh来执行
再往下看开始真正的shell代码了
# check for `cmake` command
type cmake > /dev/null 2>&1 || {
echo "\
This package requires CMake, please install it first, then you may
use this configure script to access CMake equivalent functionality.\
" >&2;
exit 1;
}
第一行仍为注释
第二行有好几处需要解释:type, cmake, >, /dev/null, 2>&1, ||
type: 是一个shell内置命令,用来查看一个命令的类型,同时也可以用于检查这个命令是否存在
cmake:一个编译工具,说明编译CAF这个开源项目需要cmake
>:重定向符号,一般情况下命令的输出都是到标准输出设备(屏幕),但是通过重定向,我们可以将命令的输出放到指定位置(文件或其他设备)
/dev/null:代表空设备文件,结合上下文,就是不要输出 type 命令产生的任何信息
2>&1:这里其实要解释几个东西,1和2在这里不是数字,而是表示文件描述符(FD),&表示等同于,结合起来就是2的输出重定向等同于1
1:其实是file descriptor 1(fd1),表示stdout标准输出, 系统的默认值为1,就是标准输出。所以">/dev/null"等价于"1>/dev/null"
2:就是fd2,表示stderr标准错误。0表示标准输入stdin
&:表示等同于
||:逻辑或符号,这里其实将前面命令的结果看成一个bool值,如果type命令成功执行,则返回值相当于true,那么就不用执行后面的内容。
如果type命令失败(没有找到cmake),就继续执行后面的内容
第三行到最后,就是找不到cmake命令时执行
echo:显示一行信息,后面可以跟字符串也可以是变量名
>&2:这里相当于 1>&2,标准输出重定向等同于标准错误,就是将这里的字符串当成error显示
exit 1:由于缺少cmake,编译环境有问题,退出执行
2. 再往下看
command="$0 $*"
dirname_0=`dirname $0`
sourcedir=`cd $dirname_0 && pwd`
benchmark_suite_options=""
if [ -d "$sourcedir/benchmarks/caf" ] ; then
benchmark_suite_options="\
Benchmark Suite Options:
--with-javac=FILE path to Java compiler
--with-java=FILE path to Java Runtime
--with-scalac=FILE path to Scala compiler
--with-erlc=FILE path to Erlang compiler
--with-charmc=FILE path to Charm++ compiler
--with-salsa=FILE path to SALSA Lite jar
"
fi
usage="\
Usage: $0 [OPTION]... [VAR=VALUE]...
Build Options:
--generator=GENERATOR set CMake generator (see cmake --help)
--build-type=TYPE set CMake build type [RelWithDebInfo]:
- Debug: debugging flags enabled
- MinSizeRel: minimal output size
- Release: optimizations on, debugging off
- RelWithDebInfo: release flags plus debugging
--build-dir=DIR place build files in directory [build]
--bin-dir=DIR executable directory [build/bin]
--lib-dir=DIR library directory [build/lib]
--with-clang=FILE path to clang++ executable
--with-gcc=FILE path to g++ executable
--dual-build build using both gcc and clang
--build-static build as static and shared library
--build-static-only build as static library only
--more-warnings enables most warnings
--no-compiler-check disable compiler version check
--no-auto-libc++ do not automatically enable libc++ for Clang
--warnings-as-errors enables -Werror
Installation Directories:
--prefix=PREFIX installation directory [/usr/local]
Remove Standard Features (even if all dependencies are available):
--no-memory-management build without memory management
--no-examples build without examples
--no-qt-examples build without Qt examples
--no-protobuf-examples build without Google Protobuf examples
--no-curl-examples build without libcurl examples
--no-unit-tests build without unit tests
--no-opencl build without opencl
--no-nexus build without nexus
--no-cash