[CMake] Linking archives in a sibling directory

Rolf Eike Beer eike at sf-mail.de
Thu Dec 2 09:36:07 EST 2010


> Hi Michael,
>
>
> On Thu, Dec 2, 2010 at 19:40, Michael Hertling <mhertling at online.de>
> wrote:
>> On 12/01/2010 06:03 PM, Raymond Wan wrote:
>>> 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 see -- I did not realize this point you made about CMake's
> dependency tracking abilities.  So, basically the only thing I need to
> worry about is the order of the ADD_SUBDIRECTORY ()'s.  As long as I
> put
>
> ADD_SUBDIRECTORY (dir-A)
>
> before
>
> ADD_SUBDIRECTORY (main)
>
> then "main" will be built correctly?
>
> But, if I am not mistaken and following what you are saying, I can
> only build "main" using the top-level CMakeLists.txt.  The lower
> CMakeLists.txt in main/ does not know the location of "dir-A".  The
> only way for both to work is to have this in main/CMakeLists.txt:
>
> ADD_SUBDIRECTORY(../dir-A ${CMAKE_CURRENT_BINARY_DIR}/dir-A)
>
> yet this kind of duplication should be an error at worse; unnecessary
> repetition at best?

Let's say you have

dirA, dirB, dirC

dirA builds a lib
dirB builds a lib that needs libA
dirC builds a target that needs libA and libB

Then you can't do


libB/CMakeLists.txt
  ADD_SUBDIRECTORY(../dirA dira)

libB/CMakeLists.txt
  ADD_SUBDIRECTORY(../dirA dira)
  ADD_SUBDIRECTORY(../dirB dirb)


CMakeLists.txt

ADD_SUBDIRECTORY(dirA)
ADD_SUBDIRECTORY(dirB)
ADD_SUBDIRECTORY(dirC)

since dirA is included twice. We have a module for that:

function (Add_Subdirectory_Once SUBDIRECTORY)
  get_filename_component(FULLPATH ${SUBDIRECTORY} REALPATH)

  GET_PROPERTY(_INCLUDED_DIRS GLOBAL PROPERTY ADD_SUBDIRECTORY_ONCE_INCLUDED)
  LIST(FIND _INCLUDED_DIRS "${FULLPATH}" _USED_INDEX)

  if(_USED_INDEX EQUAL -1)
    SET_PROPERTY(GLOBAL PROPERTY ADD_SUBDIRECTORY_ONCE_INCLUDED
"${_INCLUDED_DIRS}" "${FULLPATH}")
    if(${ARGC} EQUAL 1)
      add_subdirectory(${SUBDIRECTORY})
    else(${ARGC} EQUAL 1)
      add_subdirectory(${SUBDIRECTORY} ${ARGV1})
    endif(${ARGC} EQUAL 1)
  endif(_USED_INDEX EQUAL -1)
endfunction (Add_Subdirectory_Once)

But I would love to see this being an option in CMake, e.g.

ADD_SUBDIRECTORY(../dirA dira)
ADD_SUBDIRECTORY(../dirA diraa) # fail, defined twice

ADD_SUBDIRECTORY(../dirB dirb ONCE)
ADD_SUBDIRECTORY(../dirB dirbb ONCE) # works, since all agree that there
may be only one instance of this in the whole tree

This would allow starting at any point in the tree to build just this lib
allowing it to drag in all it's dependencies using ONCE.

This probably has other pitfalls, but for us this works pretty well.

Eike



More information about the CMake mailing list