deps.asciidoc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. == Packages and dependencies
  2. Erlang.mk can fetch and compile the dependencies that your
  3. project requires. Erlang.mk improves upon the concepts
  4. introduced by Rebar, so they should be familiar to many
  5. seasoned Erlang developers.
  6. Erlang.mk is not a package manager, nor is it trying to be,
  7. but it does include an index of Erlang packages to make
  8. discovering useful projects easier.
  9. This chapter will explain how to use packages, add
  10. dependencies to your project or bundle them directly
  11. in a single repository.
  12. === Searching packages
  13. Erlang.mk gives you access to nearly 500 packages, with more
  14. being added regularly.
  15. To find a package, search for it:
  16. [source,bash]
  17. $ make search q=pool
  18. This will return all packages matching this word, like worker
  19. pool and acceptor pool projects.
  20. You can also list everything and use regular command line
  21. tools to find what you need, for example:
  22. [source,bash]
  23. $ make search | less
  24. // @todo Simplify adding packages, add a new chapter explaining
  25. // everything, then link to this new chapter from here.
  26. === Adding dependencies to your project
  27. Once you find the package you need, adding it as a dependency
  28. to your project is a one-liner:
  29. [source,make]
  30. DEPS = cowboy
  31. And that's it! The next time you run `make`, Erlang.mk will
  32. fetch and compile Cowboy. Erlang.mk will also ensure Cowboy
  33. is available whenever you use the shell, run tests and any
  34. other operations.
  35. Erlang.mk will fill in the application resource file with
  36. all applications found in `DEPS`. But not all dependencies
  37. are Erlang applications, and not all dependencies need to
  38. be a runtime dependency. That's where the `BUILD_DEPS`
  39. variable comes in: it works just like `DEPS`, except the
  40. dependencies listed there will not be added as runtime
  41. dependencies.
  42. For example, you could add a parse transform project like
  43. this to make it available only at build time:
  44. [source,make]
  45. BUILD_DEPS = erlando
  46. Or you could depend on a C project directly, if you are
  47. building a NIF:
  48. [source,make]
  49. BUILD_DEPS = leveldb
  50. dep_leveldb = git https://github.com/basho/leveldb 2.1.3
  51. This dependency will be built before your application, so
  52. you could easily copy the resulting shared file into your
  53. 'priv/' directory as part of the build process. More information
  54. about that in the link:ports.asciidoc[NIFs and port drivers]
  55. chapter.
  56. Another variable, `LOCAL_DEPS`, allows specifying runtime
  57. dependencies which are part of Erlang/OTP itself, but also
  58. dependencies that are included in the repository. Since they
  59. are already on your system, there is no need to fetch them.
  60. Do note that there is no way to choose the version, the
  61. application used will be the one already on your system.
  62. You could depend on the Crypto application, for example:
  63. [source,make]
  64. LOCAL_DEPS = crypto
  65. Erlang.mk comes with additional types of dependencies.
  66. It has `TEST_DEPS` for dependencies used only for testing:
  67. [source,make]
  68. TEST_DEPS = ct_helper
  69. dep_ct_helper = git https://github.com/ninenines/ct_helper master
  70. `DOC_DEPS` for dependencies used only when building documentation:
  71. [source,make]
  72. DOC_DEPS = edown
  73. `REL_DEPS` for dependencies required to build the release,
  74. or to include extra applications in the release:
  75. [source,make]
  76. REL_DEPS = recon
  77. And `SHELL_DEPS` for dependencies to make available when running
  78. the `make shell` command:
  79. [source,make]
  80. SHELL_DEPS = tddreloader
  81. All these will be documented in more details in their respective
  82. chapters.
  83. ==== Modifying the dependency source or version
  84. By default, Erlang.mk will look into its package index to
  85. find the project you are looking for, if you only provide
  86. its name. This is this case:
  87. [source,make]
  88. DEPS = cowboy
  89. If you need a different version, you need to define another
  90. variable. There are two ways to do this, each being useful
  91. for different reasons.
  92. If you simply want to change the commit number, all you
  93. need to do is to define the `dep_$(DEP_NAME)_commit`
  94. variable. In the case of Cowboy, this would look like this:
  95. [source,make]
  96. DEPS = cowboy
  97. dep_cowboy_commit = 2.0.0-pre.2
  98. Erlang.mk will use the package index to get all information
  99. about Cowboy, except the commit number which will be overriden.
  100. If you need to set the fetch method or repository information
  101. too, for example because you want to use your own fork, or
  102. simply because the project is missing from the index, you
  103. can define the `dep_$(DEP_NAME)` variable with everything:
  104. [source,make]
  105. DEPS = cowboy
  106. dep_cowboy = git https://github.com/essen/cowboy 2.0.0-pre.2
  107. This will fetch Cowboy from your fork at the given commit.
  108. ==== Fetch methods
  109. Erlang.mk comes with a number of different fetch methods.
  110. You can fetch from Git, Mercurial, SVN, to name a few.
  111. There are fetch methods that will work everywhere, and
  112. fetch methods that will only work in a given environment.
  113. The following table lists all existing methods:
  114. [cols="<,2*^",options="header"]
  115. |===
  116. | Name | Format | Description
  117. | git | git repo commit | Clone the Git repository and checkout the given version
  118. | git-submodule | git-submodule | Initialize and update the Git submodule
  119. | hg | hg repo commit | Clone the Mercurial repository and update to the given version
  120. | svn | svn repo | Checkout the given SVN repository
  121. | cp | cp path/to/repo | Recursively copy a local directory
  122. | hex | hex version | Download the given project version from hex.pm
  123. | fail | N/A | Always fail, reserved for internal use
  124. | legacy | N/A | Legacy Erlang.mk fetcher, reserved for internal use
  125. |===
  126. The `git` and `hg` methods both have a repository and commit.
  127. You can use any valid commit, tag or branch in that repository
  128. for the commit value.
  129. For example, to fetch Cowboy with tag 2.0.0-pre.2 from Git:
  130. [source,make]
  131. dep_cowboy = git https://github.com/ninenines/cowboy 2.0.0-pre.2
  132. Or to fetch Ehsa tag 4.0.3 from Mercurial:
  133. [source,make]
  134. dep_ehsa = hg https://bitbucket.org/a12n/ehsa 4.0.3
  135. Git also comes with a concept of submodules. Erlang.mk can
  136. automatically initializes and updates submodules for dependencies,
  137. as long as they were added beforehand using `git submodule add`:
  138. [source,make]
  139. dep_cowboy = git-submodule
  140. The `svn` method only has a repository value, but that's
  141. simply because the SVN repository URL can also contain
  142. the path and commit.
  143. This would fetch an example project from the trunk:
  144. [source,make]
  145. dep_ex1 = svn https://example.com/svn/trunk/project/ex1
  146. And this would fetch a separate example project from a
  147. specific commit:
  148. [source,make]
  149. dep_ex2 = svn svn://example.com/svn/branches/erlang-proj/ex2@264
  150. You can copy a directory from your machine using the `cp` method.
  151. It only takes the path to copy from:
  152. [source,make]
  153. dep_cowboy = cp $(HOME)/ninenines/cowboy
  154. Finally, you can use a package from the
  155. link:https://hex.pm/[Hex repository]:
  156. [source,make]
  157. dep_cowboy = hex 1.0.3
  158. ==== Custom fetch methods
  159. If none of the existing methods fit your use, you can simply
  160. define your own. Erlang.mk will consider all variables that
  161. are named as `dep_fetch_$(METHOD)` to be available fetch
  162. methods. You can do anything inside this variable, as long
  163. as you create a folder named '$(DEPS_DIR)/$(call dep_name,$1)'.
  164. Or in layman terms, if your dependency is Cowboy, this would
  165. become 'deps/cowboy'.
  166. To give an example, this is what the Git method does:
  167. [source,make]
  168. ----
  169. define dep_fetch_git
  170. git clone -q -n -- $(call dep_repo,$1) $(DEPS_DIR)/$(call dep_name,$1); \
  171. cd $(DEPS_DIR)/$(call dep_name,$1) && git checkout -q $(call dep_commit,$1);
  172. endef
  173. ----
  174. Note that, like dependency information, this custom fetch method
  175. must be written before including 'erlang.mk'.
  176. === How deps are fetched and built
  177. The order in which dependencies are fetched and built is well
  178. defined. This means that Erlang.mk will get the same applications
  179. regardless of the command or options being used.
  180. In tree traversal terms, where the list of dependencies is a
  181. tree, Erlang.mk fetches everything using the pre-order traversal
  182. method. The steps can be summarized like this, starting from
  183. the root application:
  184. . Fetch all dependencies for the application
  185. . Build first dependency
  186. . Build Nth dependency
  187. . Build last dependency
  188. Every time a dependency is built, these same steps are followed,
  189. recursively.
  190. Do note that the first step, fetching all dependencies of
  191. an application, is not guaranteed to be ordered. The reason
  192. for this is that it is not possible to have the same dependency
  193. listed twice in a single application, and therefore there can
  194. be no conflicts. Remember, this step only fetches, at no point
  195. are different applications built in parallel.
  196. What about conflicts between the dependencies of different
  197. applications? Simple. Since builds are ordered, this means
  198. that the first version of an application that is fetched
  199. will be the one that wins.
  200. This means that if project A depends on projects B and C,
  201. in this order, and that both B and C depend on a different
  202. version of D, it will always be B's version of D that wins,
  203. because we fetch the dependencies of B before fetching
  204. those from C.
  205. Similarly, if project A depends on projects B, C and D,
  206. regardless of the order, and A, B and C depend on a
  207. different version of D, it will always be A's version
  208. that wins, because we fetch all dependencies of A before
  209. fetching those from B or C.
  210. === Ignoring unwanted dependencies
  211. Sometimes, you may want to ignore dependencies entirely.
  212. Not even fetch them. You may want to do this because a
  213. project you depend on depends on an application you do
  214. not need (like a dependency for building documentation
  215. or testing). Or maybe the dependency is already installed
  216. on your system.
  217. To ignore a dependency, simply add it to the `IGNORE_DEPS`
  218. variable:
  219. [source,make]
  220. IGNORE_DEPS += edown proper
  221. This will only ignore dependencies that are needed for
  222. building. It is therefore safe to write:
  223. [source,make]
  224. IGNORE_DEPS += edown proper
  225. TEST_DEPS = proper
  226. The PropEr application will be fetched as intended when
  227. running `make tests` or `make check`. It will however
  228. not be fetched when running `make` or `make deps`.
  229. === Dependencies directory
  230. Dependencies are fetched in '$(DEPS_DIR)'. By default this is
  231. the 'deps' directory. You can change this default, but you
  232. should only do so if it was not defined previously. Erlang.mk
  233. uses this variable to tell dependencies where to fetch their
  234. own dependencies.
  235. You will therefore need to use `?=` instead of `=`. Of course,
  236. if you know you will never use this project as a dependency,
  237. `=` will work. But to avoid it biting you later on, do this:
  238. [source,make]
  239. DEPS_DIR ?= $(CURDIR)/libs
  240. The `$(CURDIR)` part is important, otherwise dependencies of
  241. dependencies will be fetched in the wrong directory.
  242. Erlang.mk will also export the `REBAR_DEPS_DIR` variable for
  243. compatibility with Rebar build tools, as long as they are
  244. recent enough.
  245. === Dependencies local to the repository
  246. In addition to the dependencies that are fetched, Erlang.mk
  247. also allows you to have dependencies local to your repository.
  248. This kind of layout is sometimes called multi-application
  249. repositories, or repositories with multiple applications.
  250. They work exactly the same as remote dependencies, except:
  251. * They are not fetched
  252. * They are not autopatched
  253. * They are not deleted on `make distclean`
  254. * They are not automatically added to the application resource file
  255. To properly fill the application resource file, you will
  256. need to define the `LOCAL_DEPS` variable for each relevant
  257. application, the same as for OTP applications.
  258. If there is a conflict between a local dependency and a
  259. remote dependency, then the local dependency always wins;
  260. an error will be triggered when trying to fetch the
  261. conflicting remote dependency.
  262. To start using dependencies local to the repository, simply
  263. create a folder named '$(APPS_DIR)'. By default, this folder
  264. is the 'apps/' directory.
  265. You can use Erlang.mk to bootstrap local dependencies by
  266. using the command `make new-app` or `make new-lib`. This
  267. command will create the necessary directories and bootstrap
  268. the application.
  269. For example, to create a full fledged OTP application as
  270. a local dependency:
  271. [source,bash]
  272. $ make new-app in=webchat
  273. Or, the same as an OTP library:
  274. [source,bash]
  275. $ make new-lib in=webchat
  276. Templates also work with local dependencies, from the root
  277. directory of the project. You do need however to tell
  278. Erlang.mk to create the files in the correct application:
  279. [source,bash]
  280. $ make new t=gen_server n=my_server in=webchat
  281. === Repositories with no application at the root level
  282. It's possible to use Erlang.mk with only applications in
  283. '$(APPS_DIR)', and nothing at the root of the repository.
  284. Just create a folder, put the 'erlang.mk' file in it,
  285. write a Makefile that includes it, and start creating
  286. your applications.
  287. Similarly, it's possible to have a repository with only
  288. dependencies found in '$(DEPS_DIR)'. You just need to
  289. create a Makefile and specify the dependencies you want.
  290. This allows you to create a repository for handling the
  291. building of releases, for example.
  292. === Autopatch
  293. Erlang.mk will automatically patch all the dependencies it
  294. fetches. It needs to do this to ensure that the dependencies
  295. become compatible with not only Erlang.mk, but also with
  296. the version of Erlang.mk that is currently used.
  297. When fetching a dependency, the following operations are
  298. performed:
  299. * Fetch the dependency using the configured fetch method
  300. * If it contains a 'configure.ac' or 'configure.in' file, run `autoreconf -Wall -vif -I m4`
  301. * If it contains a 'configure' script, run it
  302. * Run autopatch on the project
  303. Autopatch first checks if there is any project-specific patch
  304. enabled. There are currently two: `RABBITMQ_CLIENT_PATCH` for
  305. the `amqp_client` dependency, and `RABBITMQ_SERVER_PATCH` for
  306. the `rabbit` dependency. These are needed only for RabbitMQ
  307. versions before 3.6.0 (assuming you are using upstream RabbitMQ,
  308. and not a fork).
  309. Otherwise, autopatch performs different operations depending
  310. on the kind of project it finds the dependency to be.
  311. * Rebar projects are automatically converted to use Erlang.mk
  312. as their build tool. This essentially patches Rebar out, and
  313. fixes and converts the project to be compatible with Erlang.mk.
  314. * Erlang.mk projects have their 'erlang.mk' file redirect to
  315. the top-level project's Erlang.mk. This is to ensure that
  316. functionality works across all dependencies, even if the
  317. dependency's Erlang.mk is outdated.
  318. * Other Erlang projects get a small Erlang.mk Makefile
  319. generated automatically.
  320. * Projects with no source directory and no Makefile get an
  321. empty Makefile generated, for compatibility purposes.
  322. * Other projects with no Makefile are left untouched.
  323. You can disable the replacing of the 'erlang.mk' file by
  324. defining the `NO_AUTOPATCH_ERLANG_MK` variable:
  325. [source,make]
  326. NO_AUTOPATCH_ERLANG_MK = 1
  327. You can also disable autopatch entirely for a few select
  328. projects using the `NO_AUTOPATCH` variable:
  329. [source,make]
  330. NO_AUTOPATCH = cowboy ranch cowlib
  331. === Skipping deps
  332. It is possible to temporarily skip all dependency operations.
  333. This is done by defining the `SKIP_DEPS` variable. Use cases
  334. include being somewhere with no connection to download them,
  335. or perhaps a peculiar setup.
  336. A typical usage would be:
  337. [source,bash]
  338. $ make SKIP_DEPS=1
  339. When the variable is defined:
  340. * Dependencies will not be compiled or downloaded when required
  341. * The dependency directory '$(DEPS_DIR)' will not be removed on `make distclean`
  342. This variable only applies to remote dependencies.