IMP logo
IMP Manual  for IMP version 2.19.0
extdepends.md
1 Adding external dependencies {#extdepends}
2 ============================
3 
4 [TOC]
5 
6 # Introduction # {#extdep_intro}
7 
8 You can have an %IMP module depend on some external library, for example
9 to take advantage of a method implemented in that library, or to link
10 %IMP with another piece of software at runtime.
11 
12 # Considerations # {#extdep_consider}
13 
14 Think very carefully before introducing a new external dependency. Each
15 additional dependency makes it harder for people to use your code.
16 If you do need to add a dependency, it needs to be open source and available
17 under a suitably permissive license (for %example if it is available under
18 the GPL then you cannot license your module as LGPL, but will need to also
19 make it GPL).
20 
21 Generally if you need to add a new dependency you should probably also put
22 your code in a new module, rather than adding it to an existing module. That
23 way, people that elect not to install that dependency will only be deprived
24 of your code, not of the existing module.
25 
26 Try not to require the very latest version of a dependency, as again that may
27 make it harder for people to use. (If necessary, you can use preprocessor
28 macros so that your code works with both old and new versions of a dependency;
29 for examples, look in the C++ code for `BOOST_VERSION`.) We try to make %IMP
30 work with the versions of packages available in the oldest supported versions
31 of RedHat Enterprise Linux (RHEL), Ubuntu LTS, and macOS. For example, RHEL 7
32 ships with Boost 1.53 and Python 2.7, so %IMP works with both of those.
33 
34 # Simple dependencies # {#extdep_simple}
35 
36 The simplest way to add a C/C++ dependency `foo` is to create a file
37 `foo.description` in the `dependency` subdirectory of your module. This is a
38 simple text file containing several variables:
39 
40 - `headers`: a colon-separated list of any C/C++ headers that need to be
41  included to use the dependency.
42 - `libraries`: a colon-separated list of any libraries that need to be
43  linked against to use the dependency. (There is a similar `extra_libraries`
44  variable, if needed, for libraries that aren't part of the dependency but
45  that need to also be linked in order for it to work.)
46 - `body`: a fragment of C++ code that uses the dependency.
47 
48 When CMake is run, it will use the variables in `foo.description` to build
49 a small test program in order to make sure the dependency is available and
50 that it works. See `modules/kernel/dependency/GPerfTools.description` for
51 an example.
52 
53 # More complex dependencies # {#extdep_complex}
54 
55 For more complex dependencies, you can also create a `foo.cmake` file
56 containing arbitrary CMake instructions to configure the dependency. See for
57 example `modules/rmf/dependency/RMF.cmake`.
58 
59 # Using the dependency # {#extdep_using}
60 
61 The next step in adding a `foo` dependency is to list `foo` in the module's
62 `dependencies.py` file. `foo` can be listed either in that file's
63 `required_dependencies` variable or in `optional_dependencies`, both of
64 which are colon-separated lists of external dependencies. See for example
65 `modules/kernel/dependencies.py`.
66 
67 If placed in `required_dependencies`, the module cannot be built unless your
68 dependency is found. The module will be automatically linked against the
69 dependency.
70 
71 If placed in `optional_dependencies`, the module can be built either with
72 or without the dependency. If the dependency is available, a preprocessor
73 macro will be set when the module is built; protect your code with that
74 macro. For example, IMP::score_functor can be built with or without the
75 HDF5 library. Any code that requires HDF5 is conditional on the
76 `IMP_SCORE_FUNCTOR_USE_HDF5` preprocessor macro.