[CMake] Linking archives in a sibling directory

Michael Hertling mhertling at online.de
Thu Dec 2 05:40:54 EST 2010


On 12/01/2010 06:03 PM, Raymond Wan wrote:
> Hi Michael,
> 
> 
> On Thu, Dec 2, 2010 at 01:03, Michael Hertling <mhertling at online.de> wrote:
>> On 12/01/2010 08:18 AM, Raymond Wan wrote:
>>> Hi all,
>>>
>>> I'm having a problem understanding how I can link to an archive in
>>> another directory which is not a subdirectory. For example:
>>>
>>> myproj
>>>   +-- main
>>>     +-- CMakeLists.txt
>>>     +-- source files for main program
>>>   +-- dir-A
>>>     +-- CMakeLists.txt
>>>     +-- source files for sub-program A
>>>   +-- dir-B
>>>     +-- CmakeLists.txt
>>>     +-- source files for sub-program B
>>
>> This error is caused by the fact that the directory "dir-A" is outside
>> the "main" directory tree, so dir-A's binary directory would likewise
>> be outside main's binary tree, and this is reasonably forbidden when
>> configuring "main". You might specify dir-A's binary directory in
>> main/CMakeLists.txt explicitly, e.g.:
>>
>> ADD_SUBDIRECTORY(../dir-A ${CMAKE_CURRENT_BINARY_DIR}/dir-A)
>>
>> Hence, subprogA_ar will be built within the binary tree's "dir-A".
> 
> 
> Ah!  I see now.  I didn't realize I could prepend a path like that.  I
> was trying to find some kind of "ADD_DIRECTORY" command which had this
> restriction removed.  But then I realized if I'm looking for something
> like that, there might be a bigger problem in terms of how I'm
> organizing things...
> 
> 
>>> myproj
>>>   +-- main
>>>     +-- CMakeLists.txt
>>>     +-- source files for main program
>>>     +-- dir-A
>>>       +-- source files for sub-program A
>>>     +-- dir-B
>>>       +-- source files for sub-program B
>>>
>>>
>>> Is this what I should have done??
>>
>> As an alternative, consider to add a CMakeLists.txt in "myproj"
>>
>> CMAKE_MINIMUM_REQUIRED(...)
>> PROJECT(myproj)
>> ADD_SUBDIRECTORY(dir-A)
>> ADD_SUBDIRECTORY(dir-B)
>> ADD_SUBDIRECTORY(main)
>>
>> and subsequently, configure this directory instead of "main".
> 
> 
> Ah!  I see.  Then is it recommended that this top-level CMakeLists.txt
> have just these lines, or should I move the ADD_EXECUTABLE, etc. lines
> here as well?  Or is this really "up to me" and there isn't a
> suggested paradigm?

Basically, IMO, a CMakeLists.txt with ADD_EXECUTABLE() et al. should be
placed in the same directory as the related source files unless there's
a reason not to do so; this makes for modularity and a well organized
code base. The above-mentioned directory structure with its top-level
CMakeLists.txt containing just ADD_SUBDIRECTORY() commands keeps the
modules main, dir-A and dir-B separate with minimal interconnections.
In the previous structure, e.g., main/CMakeLists.txt had to know that
dir-A resides in "../dir-A"; now, such information is concentrated in
the top-level CMakeLists.txt, and the sole reference of main to dir-A
is the target "subprogA_ar". Due to CMake's capabilities to track the
dependencies among targets, it doesn't matter where dir-A is placed
within the project's source tree. So, in short, don't move the
ADD_EXECUTABLE() etc. to the top-level CMakeLists.txt.

> I guess I chose my first directory layout because the source in a
> directory (i.e., dir-A) can be several dependencies down and it can
> even be used by two targets in two different directories.  So, I
> figured that keeping them all at the "same directory level" would be
> best.  But it seems what you're suggesting here seems better -- never
> thought of it; the "myproj" directory has no files in it...just
> directories right now...

The top-level directory of non-trivial projects should not contain any
source files, perhaps a config.h header or the like. Usually, there're
enough things gathering in a project's root, e.g. READMEs, subdirs for
documentation, resources or CMake stuff, a CMakeLists.txt file ;) etc.
The sources, however, should be organized in their own subdirectories,
so the top-level CMakeLists.txt typically contains ADD_SUBDIRECTORY()
commands along with configurational stuff like setting up compiler
flags, processing options or investigating the underlying system,
but no ADD_EXECUTABLE() or the like.

Of course, there're exceptions and probably strong different opinions.

Regards,

Michael


More information about the CMake mailing list