[CMake] Adding a dependency

Philip Lowman philip at yhbt.com
Sun Jan 25 10:02:08 EST 2009


On Fri, Jan 23, 2009 at 1:11 PM, Wade Williams <wadesworld at mac.com> wrote:

> I have a project structure that looks like this:
> project
> |
> | - lib
> | ----bin
> | ----util
> | --------inc
> | --------src
> | - app
> | ----bin
> | ----inc
> | ----src
>
> In short, each library in the project lives under project/lib.  Built
> libraries are stored in project/lib/bin.  Each library subdirectory (i.e.
> util) has a CMakeLists.txt to build that particular library.  In the lib
> folder is a CMakeLists.txt which does add_subdirectory() on all the
> subdirectories.  So far, so good - works like a charm.
>
> The executable lives under project/app.  The built executable is stored in
> project/app/bin.  There is a CMakeLists.txt in project/app to build the
> application executable.
>
> Now for the problem.  How do I add the libraries as dependencies?
>
> I can't use add_dependencies() because the app/CMakeLists.txt doesn't know
> about the targets in the library directories.  I suppose I could do:
>
> add_subdirectory(../../lib ../../lib/bin)
>
> so it would know about those targets, but that doesn't seem the right
> solution.
>
> I can certainly use find_library() to add the built libraries to my
> executable, but then my executable is not dependent upon being them and
> linking will fail if make was not executed in lib first.
>
> Now, I certainly plan to have a project/CMakeLists.txt file that does
> add_subdirectory() on lib and app.  Thus, if someone builds from that top
> level, it should all work if I use find_library() at the application level.
>  However, I'd like it also to work if someone cd's into the application
> directory and types "cmake . ; make".
>
> Any thoughts?
>

You shouldn't need to use find_library() to detect internally built
libraries.  This was not the intention of that command which is instead
meant to facilitate linking against externally provided libraries.  You
should instead be using target_link_libraries() which handles dependencies
automatically.

If someone types "make" in the app directory after typing "cmake . ; make"
from the toplevel here is what should happen:

1. All targets added at the app folder or beneath will be queued for
building by default

2. Presuming you have created a myapp target which is linked to a mylib
library in the "lib" folder using target_link_libraries(), make will first
compile and link mylib.  Then make will compile and link myapp.

To get this functionality simply call
   target_link_libraries(myapp mylib)
in app/CMakeLists.txt

You'll also need to ensure that you call "ADD_SUBDIRECTORY(lib)" before the
"ADD_SUBDIRECTORY(app)" otherwise the mylib target won't exist and you'll
get a CMake error.

As for ADD_SUBDIRECTORY(../lib) I wouldn't recommend it although I believe
it will work.  The simplest approach is to do your ADD_SUBDIRECTORY() at the
toplevel and assume the user will always configure from the toplevel.  If
you have some reason to think they might want to configure from a
subdirectory check your premises first.  Usually if you want only certain
subdirectories to build you can facilitate this with OPTION()

OPTION(BUILD_MAIN_APP "Build the main application" ON)
IF(BUILD_MAIN_APP)
   ADD_SUBDIRECTORY(app)
ENDIF()


-- 
Philip Lowman
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20090125/f5e32d73/attachment-0001.htm>


More information about the CMake mailing list