我的有道云 http://note.youdao.com/noteshare ... 1F0BA2902252E500267
#### 包和依赖项(Packages and dependencies)
##### 查找包(Searching packages)
```
make search
make search | less
```
查看所有能使用的包
```
make search q=cowboy
```
##### 添加依赖包( Adding dependencies to your project)
```
DEPS = cowboy
```
加了这个参数,erlang.mk会保证cowboy能运行在shell、run、tests命令的时候
如果依赖包不用在erlang运行的时候跑的话,那就把它设置为BUILD_DEPS就行了,这样就只有构建的时候会用到
```
BUILD_DEPS = erlando
```
或者你直接依赖c项目,构建nif
```
BUILD_DEPS = leveldb
dep_leveldb = git https://github.com/basho/leveldb 2.1.3
```
这样做,依赖会比你的应用先被构建,你就可以把它生成的共享文件作为你构建过程中的一部分
本地依赖比较容易理解,就是otp内部项目的依赖:
```
LOCAL_DEPS = crypto
```
还有专为测试用的TEST_DEPS,只有当测试的时候才会运行
```
TEST_DEPS = ct_helper
dep_ct_helper = git https://github.com/ninenines/ct_helper master
```
文档专用
```
DOC_DEPS = recon
```
生成文档的时候会被用到的依赖项
shell专用依赖项
```
SHELL_DEPS = tddreloader
```
用户执行make shell命令的时候会用到的依赖
##### 修改依赖项或者版本(Modifying the dependency source or version)
当我们用到cowboy,但是erlang.mk的版本不是我想要的,这时候就可以用```dep_$(DEP_NAME)_commit```变量
```
DEPS = cowoby
dep_cowboy_commit = 2.0.0-pre.2
```
这个办法只改变版本号,依赖项还是由erlang.mk决定的,你要从其它途径获得依赖项,可以用```dep_$(DEP_NAME)```参数
```
DEPS = cowoby
dep_cowoby = git https://github.com/essen/cowboy 2.0.0-pre.2
```
这样做就会从你指定的git上获取依赖项
##### 获取方式(Fetch methods)
名 | 格式 | 描述
--- | --- | ---
git | git repo commit | 从git克隆或者checkout指定的版本
git-submodule | git-submodule | 初始化或更新git的子模块
hg | hg repo commit | 克隆Mercurial存储库并更新到给定版本
svn | svn repo | checkout指定的svn库
cp | cp /path/to/repo | 递归复制本地目录的文件
ln | ln path/to/repo | 软(符号)链接到一个路径
hex | hex version | 从hex.pm下载指定项目版本
fail | N/A | 总是失败,内部使用
legacy | N/A | erlang.mk遗留的提取程序,内部使用
git和hg的方式很相似,都有代码仓库和提交版本,可以用提交记录,标签或者分支来获取依赖
```
dep_cowboy = git https://github.com/ninenines/cowboy 2.0.0-pre.2
dep_ehsa = hg https://bitbucket.org/a12n/ehsa 4.0.3
```
但是git可以更新或者添加子模块的依赖
```
dep_cowboy = git-submodule
```
svn的方式只有一个版本库,它通过路径来指定项
```
dep_ex1 = svn https://example.com/svn/trunk/project/ex1
```
也可以获取单独的示例项目
```
dep_ex2 = svn svn://example.com/svn/branches/erlang-proj/ex2@264
```
直接本地复制的获取依赖项方式
```
dep_cowboy = cp $(HOME)/ninenines/cowboy
```
hex方式
```
dep_cowboy = hex 1.0.3
```
##### 自定义提取方法(Custom fetch methods)
```dep_fetch_(METHOD)``` 变量用来定义提取方法,只要你创建了 ```$(DEPS_DIR)/$(call dep_name, $1)```文件夹,你在这个变量中做任何事
```
define dep_fetch_git
git clone -q -n -- $(call dep_repo,$1) $(DEPS_DIR)/$(call dep_name,$1); \
cd $(DEPS_DIR)/$(call dep_name,$1) && git checkout -q $(call dep_commit,$1);
endef
```
获取方式必须在你使用之前被定义
##### 依赖项的获取和构建(How deps are fetched and built)
获取构建顺序大概如下
1. 为应用拉取所有依赖项
2. 构建第一个依赖项
3. 构建第N个依赖项
4. 构建最后依赖项
每次构建后,都是相同的方式递归进行
同一个应用拉取依赖项的时候并不一定按顺序获取依赖,因为不可能有重复的依赖项存在
如果不同应用之间有相同依赖项被拉取,这时以先到者为准,冲突什么的不存在的
还要注意,拉取和构建不是并行的,先拉取所有依赖项之后才开始构建
##### 只拉取和只列出依赖项(Fetching and listing dependencies only)
只拉取依赖项
```
make fetch-deps
```
只列出依赖项
```
make list-deps
```
但是这只是针对```DEPS```和```BUILD_DEPS```参数的依赖项,上面我们还提到了```TEST_DEPS```、```DOC_DEPS```、```REL_DEPS```和```SHELL_DEPS```,这些怎么办呢?有两个办法:
1. 用下面命令
```
make fetch-test-deps
make fetch-doc-deps
make fetch-rel-deps
make fetch-shell-deps
make list-test-deps
make list-doc-deps
make list-rel-deps
make list-shell-deps
```
2. 或者在```make fetch-deps```或```make list-deps```后面接```DEP_TYPES```参数,参数值可以是test, doc, rel和shell,例如```list-deps DEP_TYPES='test doc'```
无论用哪个方式,```BUILD_DEPS```和```DEPS```永远都在内
还需要注意的是,上面的办法都只是针对你应用的依赖项,而不会有你依赖项的依赖项
erlang.mk内部,make fetch-*命令把整个依赖项列表保存到下面一些变量名:
```
$(ERLANG_MK_RECURSIVE_DEPS_LIST)
$(ERLANG_MK_RECURSIVE_TEST_DEPS_LIST)
$(ERLANG_MK_RECURSIVE_DOC_DEPS_LIST)
$(ERLANG_MK_RECURSIVE_REL_DEPS_LIST)
$(ERLANG_MK_RECURSIVE_SHELL_DEPS_LIST)
```
而这些将在make list-*命令的时候被打印出来
##### 忽略不想要的依赖项(Ignoring unwanted dependencies)
不想要依赖项
```
IGNORE_DEPS += edown proper
```
如果这样写
```
IGNORE_DEPS += edown proper
TEST_DEPS = proper
```
意味着make和make deps命令将不拉取proper应用,而make test和make check命令还是会拉取proper应用
##### 依赖目录(Dependencies directory)
依赖项拉取到```$(DEPS_DIR)```目录下,默认名是```deps```
你可以修改默认路径,前提是你之前没有定义过它,erlang.mk靠这个变量告诉依赖项到哪里拿到自己的依赖项
所以你应该用```?=```而不是```=```去修改它(```=```支取最后一次赋值的值,```?=```如果没有赋过值,则等于后面的值)
不过如果你敢保证没有用到这个项目作为依赖项,直接用```=```也是没问题的,为了避免麻烦,还是这样做吧
```
DEPS_DIR ?= $(CURDIR)/libs
```
##### 多应用程序存储库(Many applications in one repository)
就是应用本身,还引用了本地另外一个项目作为依赖项,所以叫多应用程序
这种依赖项和远程依赖项差不多,不同的有以下几点:
1. 不用拉取
2. 不会自动封装
3. ```make distclean```的时候不会删除
4. 不会自动添加到应用程序资源文件(.app文件)
要正确填好.app文件和编译应用,首先要先定义LOCAL_DEPS变量,它的编译规则和DEPS变量是一样的
如果LOCAL_DEPS被定义了,则决定哪些apps将被构建(包括依赖项),哪些将被添加到.app文件(假如有的话)
这可以用来指定不同版本构建不同release,如果```LOCAL_DEPS```没有定义,则所有在```$(APPS_DIR)```的apps都将被构建,但是没有app会被加到.app文件
如果出现远程依赖和本地依赖冲突,本地依赖为准,并会引发拉取远程依赖冲突错误
要使用本地依赖库,只要创建名为```$(APPS_DIR)```目录就行了,默认路径是```apps/```
```make new-app```或者```make new-lib```创建本地依赖库到指定目录,例如:
```
make new-app in=webchat
make new-lib in=webchat
```
创建模板也可以用本地依赖库
```
make new t=gen_server n=my_server in=webchat
```
##### 自动修补(autopatch)
erlang.mk会自动修补拉取的所有依赖项,这是为了兼容各个正在使用的erlang.mk版本
拉取依赖项的时候,会执行以下操作:
- 按照拉取方法拉取依赖项
- 如果包含有config.ac或者config.in文件,运行autoreconf -Wall -vif -I m4
- 如果包含config脚本,运行脚本
- 在项目中运行autopatch
autopatch首先检查是否启用了项目指定的修补程序,例如```amqp_client```依赖项的```RABBITMQ_CLIENT_PATCH```,或者```rabbit```依赖项的```RABBITMQ_SERVER_PATCH```,这些只有RabbitMQkpg3.6.0才需要的参数
好吧,说实话这部分看不懂,感觉有点费解,直接上原文吧
- Rebar projects are automatically converted to use Erlang.mk as their build tool. This essentially patches Rebar out, and fixes and converts the project to be compatible with Erlang.mk.
- Erlang.mk projects have their Makefile patched, if necessary, to include the top-level project’s Erlang.mk. This is to ensure that functionality works across all dependencies, even if the dependency’s Erlang.mk is outdated. The patched Makefile can be safely committed if necessary.
- Other Erlang projects get a small Erlang.mk Makefile generated automatically.
- Projects with no source directory and no Makefile get an empty Makefile generated, for compatibility purposes.
- Other projects with no Makefile are left untouched.
你可以停止erlang.mk的替换通过```NO_AUTOPATH_ERLANG_MK```参数
```
NO_AUTOPATCH_ERLNAG_MK = 1
```
你也可以让一些项目完全停止autopatch
```
NO_AUTOPATCH = cowboy ranch cowlib
```
##### 跳过依赖项(Skipping deps)
比如不想编译依赖项
```
make SKIP_DEPS=1
```
如果启用这个参数:
- ```make distclean```命令将不移除```$(DEPS_DIR)```文件
- 依赖项将不被下载和编译
|