<div class="gmail_quote">On Fri, Jan 23, 2009 at 1:11 PM, Wade Williams <span dir="ltr"><<a href="mailto:wadesworld@mac.com">wadesworld@mac.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div style=""><font face="Monaco">I have a project structure that looks like this:</font><div><font face="Monaco"><br></font></div><div><font face="Monaco">project</font></div><div><font face="Monaco">|</font></div><div><font face="Monaco">| - lib</font></div>
<div><font face="Monaco">| ----bin</font></div><div><font face="Monaco">| ----util</font></div><div><font face="Monaco">| --------inc</font></div><div><font face="Monaco">| --------src</font></div><div><font face="Monaco">| - app</font></div>
<div><font face="Monaco">| ----bin</font></div><div><font face="Monaco">| ----inc</font></div><div><font face="Monaco">| ----src</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco">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.</font></div>
<div><font face="Monaco"><br></font></div><div><font face="Monaco">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.</font></div>
<div><font face="Monaco"><br></font></div><div><font face="Monaco">Now for the problem. How do I add the libraries as dependencies?</font></div><div><br></div><div><font face="Monaco">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:</font></div>
<div><font face="Monaco"><br></font></div><div><font face="Monaco">add_subdirectory(../../lib ../../lib/bin)</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco">so it would know about those targets, but that doesn't seem the right solution.</font></div>
<div><font face="Monaco"><br></font></div><div><font face="Monaco">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.</font></div>
<div><font face="Monaco"><br></font></div><div><font face="Monaco">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". </font></div>
<div><font face="Monaco"><br></font></div><div><font face="Monaco">Any thoughts?</font></div><div><font face="Monaco"></font></div></div></blockquote></div><br>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.<br>
<br>If someone types "make" in the app directory after typing "cmake . ; make" from the toplevel here is what should happen:<br><br>1. All targets added at the app folder or beneath will be queued for building by default<br>
<br>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.<br>
<br>To get this functionality simply call<br> target_link_libraries(myapp mylib)<br>in app/CMakeLists.txt<br><br>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.<br>
<br>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()<br>
<br>OPTION(BUILD_MAIN_APP "Build the main application" ON)<br>IF(BUILD_MAIN_APP)<br> ADD_SUBDIRECTORY(app)<br>ENDIF()<br><br><br>-- <br>Philip Lowman<br>