Linking archives in a sibling directory

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Linking archives in a sibling directory

Raymond Wan
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


Basically, I would like to make a larger project (main) and I'm
building and testing each of its components separately.

Right now, the main's CMakeLists.txt looks something like this:


INCLUDE_DIRECTORIES (../dir-A)
SUBDIRS (../dir-A)
ADD_EXECUTABLE (main ${MAIN_SRCS})
TARGET_LINK_LIBRARIES (main subprogA_ar)


which works fine so far (the CMakeLists.txt in dir-A generates the
archive subprogA_ar).

However, I just found out that SUBDIRS is deprecated and so, replaced
it with "ADD_SUBDIRECTORY".  That's when I got an error about "dir-A"
not being a subdirectory.  Obviously, I was not using "SUBDIRS" before
as it was intended...  :-)

I've also tried adding "dir-A" as a LINK_DIRECTORIES with no success.
It is unable to find subprogA_ar.

I'm not sure if it is possible, but ideally, when I run "make" in
main/, I would like it to rebuild the targets in "dir-A" (including
the archive) and link that in.

I'm also open to the possibility that I got the above organization all
wrong and should have only one large CMakeLists.txt in a directory
structure like this:


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??

Thank you!

Ray
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Michael Hertling
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
>
>
> Basically, I would like to make a larger project (main) and I'm
> building and testing each of its components separately.
>
> Right now, the main's CMakeLists.txt looks something like this:
>
>
> INCLUDE_DIRECTORIES (../dir-A)
> SUBDIRS (../dir-A)
> ADD_EXECUTABLE (main ${MAIN_SRCS})
> TARGET_LINK_LIBRARIES (main subprogA_ar)
>
>
> which works fine so far (the CMakeLists.txt in dir-A generates the
> archive subprogA_ar).
>
> However, I just found out that SUBDIRS is deprecated and so, replaced
> it with "ADD_SUBDIRECTORY".  That's when I got an error about "dir-A"
> not being a subdirectory.  Obviously, I was not using "SUBDIRS" before
> as it was intended...  :-)

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".

> I've also tried adding "dir-A" as a LINK_DIRECTORIES with no success.
> It is unable to find subprogA_ar.
>
> I'm not sure if it is possible, but ideally, when I run "make" in
> main/, I would like it to rebuild the targets in "dir-A" (including
> the archive) and link that in.
>
> I'm also open to the possibility that I got the above organization all
> wrong and should have only one large CMakeLists.txt in a directory
> structure like this:
>
>
> 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".

Regards,

Michael
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Raymond Wan
Hi Michael,


On Thu, Dec 2, 2010 at 01:03, Michael Hertling <[hidden email]> 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?

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...

Thank you for your advice!

Ray
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Michael Hertling
On 12/01/2010 06:03 PM, Raymond Wan wrote:

> Hi Michael,
>
>
> On Thu, Dec 2, 2010 at 01:03, Michael Hertling <[hidden email]> 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
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

David Cole
On Thu, Dec 2, 2010 at 5:40 AM, Michael Hertling <[hidden email]> wrote:
On 12/01/2010 06:03 PM, Raymond Wan wrote:
> Hi Michael,
>
>
> On Thu, Dec 2, 2010 at 01:03, Michael Hertling <[hidden email]> 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

Exceptions? I can't think of any... I think you're absolutely correct for any non-trivial project.
 
 
and probably strong different opinions.

If there are, then they're just plain wrong. :-)


Thanks, Michael, for your contributions to the CMake mailing list. You provide invaluable advice and assistance for many.

Cheers,
David


 

Regards,

Michael
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake


_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Raymond Wan
In reply to this post by Michael Hertling
Hi Michael,


On Thu, Dec 2, 2010 at 19:40, Michael Hertling <[hidden email]> 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?


> 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.


I see!  Thank you for this!  I'll stick with standard practice for now
and leave the exceptions and stronger opposing opinions to people who
know more about CMake than me.  :-)

Thank you very much for the explanation!

Ray
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Rolf Eike Beer
> Hi Michael,
>
>
> On Thu, Dec 2, 2010 at 19:40, Michael Hertling <[hidden email]>
> 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

_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Raymond Wan
Hi Rolf,


On Thu, Dec 2, 2010 at 23:36, Rolf Eike Beer <[hidden email]> wrote:

> 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)


Yes -- that's exactly what I was trying to say.  Thank you for the example!

I suppose the default behavior of ADD_SUBDIRECTORY is understandable
since it is meant to catch duplicate names.  By this I mean that maybe
its aim was to catch these problems when they are caused by human
error.


> since dirA is included twice. We have a module for that:
>
> function (Add_Subdirectory_Once SUBDIRECTORY)
...


Thank you for this!  I presume by "We" you mean you and your
organization?  That is, this function isn't in CMake.

I'll give it a try and see if it solves my problems.  Thank you all
for your explanations!

Ray
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Michael Hertling
In reply to this post by Raymond Wan
On 12/02/2010 03:13 PM, Raymond Wan wrote:

> Hi Michael,
>
>
> On Thu, Dec 2, 2010 at 19:40, Michael Hertling <[hidden email]> 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?

Even this is not necessary if the only reference of main to dir-A is
TARGET_LINK_LIBRARIES(... subprogA_ar) in main/CMakeLists.txt since
TARGET_LINK_LIBARIES(), AFAIK, does a lazy evaluation of the targets'
dependencies, i.e. they are evaluated when all CMakeLists.txt files
have been processed and, hence, all dependencies are known. If you
refer to subprogA_ar in another way, e.g. SET_TARGET_PROPERTIES(),
then you will get an error if dir-A hasn't been configured yet.

> 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?

Each invocation of ADD_SUBDIRECTORY() for a source directory must be
associated with an own binary directory, so the above-mentioned line
would allow you to use both alternatives. However, when configuring
the top-level CMakeLists.txt, you will get an error due to multiple
definitions of the subprogA_ar target. In main/CMakeLists.txt, you
might protect ADD_SUBDIRECTORY() against multiple invocations like

IF(NOT TARGET subprogA_ar)
   ADD_SUBDIRECTORY(../dir-A ${CMAKE_CURRENT_BINARY_DIR}/dir-A)
ENDIF()

or

IF(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR})
   ADD_SUBDIRECTORY(../dir-A ${CMAKE_CURRENT_BINARY_DIR}/dir-A)
ENDIF()

but this does not appear really appropriate to me.

Nevertheless, I wonder why you want to build "main" by configuring its
own source directory and alternatively via the top-level directory. If
this is because you'd like to exclude some modules from building, you
should handle such things in the top-level CMakeLists.txt, e.g. like:

# Define options:
OPTION(WITH_MAIN "Build module main" ON)
OPTION(WITH_A "Build module A" ON)
OPTION(WITH_B "Build module B" ON)

# Handle dependencies:
IF(WITH_MAIN)
    SET(WITH_A ON)
ENDIF()

# Enable modules:
IF(WITH_B)
    ADD_SUBDIRECTORY(dir-B)
ENDIF()
IF(WITH_A)
    ADD_SUBDIRECTORY(dir-A)
ENDIF()
IF(WITH_MAIN)
    ADD_SUBDIRECTORY(main)
ENDIF()

So, you can conveniently enable/disable the modules on the command line
or in the GUI, e.g. with "cmake -DWITH_B=OFF <path/to/top-level-dir>"
if you don't want to build module B.

As an alternative, you might consider to move dir-A to main/dir-A if
dir-A is essentially a submodule of main, but referring to a sibling
dir-A from main indicates that the latter is not sufficiently self-
contained to be built on its own with a "cmake <path/to/main>", so
the modules' relationships should be handled by other means, IMO.

Regards,

Michael

>> 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.
>
>
> I see!  Thank you for this!  I'll stick with standard practice for now
> and leave the exceptions and stronger opposing opinions to people who
> know more about CMake than me.  :-)
>
> Thank you very much for the explanation!
>
> Ray
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Raymond Wan
Hi Michael,

Thank you for your continued advice!


On Fri, Dec 3, 2010 at 19:13, Michael Hertling <[hidden email]> wrote:

> On 12/02/2010 03:13 PM, Raymond Wan wrote:
>> ADD_SUBDIRECTORY (dir-A)
>>
>> before
>>
>> ADD_SUBDIRECTORY (main)
>>
>> then "main" will be built correctly?
>
> Even this is not necessary if the only reference of main to dir-A is
> TARGET_LINK_LIBRARIES(... subprogA_ar) in main/CMakeLists.txt since
> TARGET_LINK_LIBARIES(), AFAIK, does a lazy evaluation of the targets'
> dependencies, i.e. they are evaluated when all CMakeLists.txt files
> have been processed and, hence, all dependencies are known. If you
> refer to subprogA_ar in another way, e.g. SET_TARGET_PROPERTIES(),
> then you will get an error if dir-A hasn't been configured yet.


I see; I am using just TARGET_LINK_LIBRARIES (), so that is good to
know that I don't need to worry about the ordering.  Thank you!


>> 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?
>
> Each invocation of ADD_SUBDIRECTORY() for a source directory must be
> associated with an own binary directory, so the above-mentioned line
> would allow you to use both alternatives. However, when configuring
> the top-level CMakeLists.txt, you will get an error due to multiple
> definitions of the subprogA_ar target. In main/CMakeLists.txt, you
> might protect ADD_SUBDIRECTORY() against multiple invocations like
>
> IF(NOT TARGET subprogA_ar)
>   ADD_SUBDIRECTORY(../dir-A ${CMAKE_CURRENT_BINARY_DIR}/dir-A)
> ENDIF()
>
> or
>
> IF(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR})
>   ADD_SUBDIRECTORY(../dir-A ${CMAKE_CURRENT_BINARY_DIR}/dir-A)
> ENDIF()
>
> but this does not appear really appropriate to me.
>
> Nevertheless, I wonder why you want to build "main" by configuring its
> own source directory and alternatively via the top-level directory. If
> this is because you'd like to exclude some modules from building, you
> should handle such things in the top-level CMakeLists.txt, e.g. like:
>
> # Define options:
> OPTION(WITH_MAIN "Build module main" ON)
> OPTION(WITH_A "Build module A" ON)
> OPTION(WITH_B "Build module B" ON)
>
> # Handle dependencies:
> IF(WITH_MAIN)
>    SET(WITH_A ON)
> ENDIF()
>
> # Enable modules:
> IF(WITH_B)
>    ADD_SUBDIRECTORY(dir-B)
> ENDIF()
> IF(WITH_A)
>    ADD_SUBDIRECTORY(dir-A)
> ENDIF()
> IF(WITH_MAIN)
>    ADD_SUBDIRECTORY(main)
> ENDIF()
>
> So, you can conveniently enable/disable the modules on the command line
> or in the GUI, e.g. with "cmake -DWITH_B=OFF <path/to/top-level-dir>"
> if you don't want to build module B.
>
> As an alternative, you might consider to move dir-A to main/dir-A if
> dir-A is essentially a submodule of main, but referring to a sibling
> dir-A from main indicates that the latter is not sufficiently self-
> contained to be built on its own with a "cmake <path/to/main>", so
> the modules' relationships should be handled by other means, IMO.


Hmmmmm, I see your point about why I'm providing support in a
top-level CMakeLists.txt and a lower level one.  Perhaps I've simply
confused myself and made things more complicated than it needs to be.
Basically, what I want to do is, given this directory structure:

myproj/
  +dirA/
  +dirB/
  +dirC/
  +main1/
  +main2/
  +main3/

my final goal is that several programs (i.e., executables) will be
made.  Let's say main1, main2, and main3.  The libraries dirA, ...,
dirD are used by them and can also depend on each other with maybe
even multiple levels of dependencies.  i.e.,

dirA --> dirB --> dirC

Any of these modules can be used by more than one program.  i.e.,

main1 --> dirA --> dirB --> dirC
main2 --> dirC

My idea is that the top level CMakeLists.txt can create main1, main2,
and main3.  The lower level CMakeLists.txt in dirA/, dirB/, and dirC/
have their own main () which I am using to test them -- obviously,
these main () functions are not linked into main1, main2, and main3.
I only need them for development.  I think organizing dirA/, dirB/,
and dirC/ within main1/, main2/, and main3/ isn't the way to go since
these libraries are used by multiple executables.

Perhaps I should create and use the low-level CMakeLists.txt and when
I am finished development, then create the top-level ones for just
main1, main2, and main3.  In a way, I will only need to support either
the top-level CMakeLists.txt or the lower level one and never both at
the same time.  I guess I am ahead of myself and did both now, which
is complicating things for me.

Hmmmm, I need to give this a bit more thought -- any suggestions
welcome...  Thank you!

Ray
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Michael Hertling
On 12/03/2010 04:26 PM, Raymond Wan wrote:

> Hi Michael,
>
> Thank you for your continued advice!
>
>
> On Fri, Dec 3, 2010 at 19:13, Michael Hertling <[hidden email]> wrote:
>> Nevertheless, I wonder why you want to build "main" by configuring its
>> own source directory and alternatively via the top-level directory. If
>> this is because you'd like to exclude some modules from building, you
>> should handle such things in the top-level CMakeLists.txt, e.g. like:
>>
>> # Define options:
>> OPTION(WITH_MAIN "Build module main" ON)
>> OPTION(WITH_A "Build module A" ON)
>> OPTION(WITH_B "Build module B" ON)
>>
>> # Handle dependencies:
>> IF(WITH_MAIN)
>>    SET(WITH_A ON)
>> ENDIF()
>>
>> # Enable modules:
>> IF(WITH_B)
>>    ADD_SUBDIRECTORY(dir-B)
>> ENDIF()
>> IF(WITH_A)
>>    ADD_SUBDIRECTORY(dir-A)
>> ENDIF()
>> IF(WITH_MAIN)
>>    ADD_SUBDIRECTORY(main)
>> ENDIF()
>>
>> So, you can conveniently enable/disable the modules on the command line
>> or in the GUI, e.g. with "cmake -DWITH_B=OFF <path/to/top-level-dir>"
>> if you don't want to build module B.
>>
>> As an alternative, you might consider to move dir-A to main/dir-A if
>> dir-A is essentially a submodule of main, but referring to a sibling
>> dir-A from main indicates that the latter is not sufficiently self-
>> contained to be built on its own with a "cmake <path/to/main>", so
>> the modules' relationships should be handled by other means, IMO.
>
>
> Hmmmmm, I see your point about why I'm providing support in a
> top-level CMakeLists.txt and a lower level one.  Perhaps I've simply
> confused myself and made things more complicated than it needs to be.
> Basically, what I want to do is, given this directory structure:
>
> myproj/
>   +dirA/
>   +dirB/
>   +dirC/
>   +main1/
>   +main2/
>   +main3/
>
> my final goal is that several programs (i.e., executables) will be
> made.  Let's say main1, main2, and main3.  The libraries dirA, ...,
> dirD are used by them and can also depend on each other with maybe
> even multiple levels of dependencies.  i.e.,
>
> dirA --> dirB --> dirC
>
> Any of these modules can be used by more than one program.  i.e.,
>
> main1 --> dirA --> dirB --> dirC
> main2 --> dirC
>
> My idea is that the top level CMakeLists.txt can create main1, main2,
> and main3.  The lower level CMakeLists.txt in dirA/, dirB/, and dirC/
> have their own main () which I am using to test them -- obviously,
> these main () functions are not linked into main1, main2, and main3.
> I only need them for development.  I think organizing dirA/, dirB/,
> and dirC/ within main1/, main2/, and main3/ isn't the way to go since
> these libraries are used by multiple executables.

Yes, absolutely, with such relations among executables and libraries,
their source directories should be siblings instead of descendants, and
the libraries' testing executables can be conveniently integrated using
ADD_TEST() without interfering with the main executables. However, when
your project grows and, hence, the number of source directories in the
project's root increases, say 10+, you should consider to organize them
further, e.g. like

myproj
  executables
    main{1,2,3,...}
  libraries
    dir{A,B,C,...}
  plugins
    ...

or

myproj
  source
    core
      ...
    gui
      ...
    db
      ...

or whichever organizational criteria apply best, so the root directory
doesn't fill with countless source directories. Apart from that, there
is no need to have the top-level CMakeLists.txt create the main{1,2,3}
executables by itself; just add a CMakeLists.txt file in each of their
source directories as you do for the libraries, and use

ADD_SUBDIRECTORY(main1)
ADD_SUBDIRECTORY(main2)
ADD_SUBDIRECTORY(main3)

at the top level to enable them. In this way, you've a CMakeLists.txt
file in each of your project's source directories which does exactly
what needs to be done there, and the whole project is covered by the
top-level CMakeLists.txt with minimal assumptions w.r.t. the source
directories.

> Perhaps I should create and use the low-level CMakeLists.txt and when
> I am finished development, then create the top-level ones for just
> main1, main2, and main3.  In a way, I will only need to support either
> the top-level CMakeLists.txt or the lower level one and never both at
> the same time.  I guess I am ahead of myself and did both now, which
> is complicating things for me.

IMO, there is no reason to configure with lower-level CMakeLists.txt
files at first and switch to a top-level CMakeLists.txt later. Instead,
start right away with one CMakeLists.txt file per source directory and
one top-level CMakeLists.txt, and whenever a new source directory with
its own CMakeLists.txt is added to your project, just add an according
ADD_SUBDIRECTORY() at the top level, too. So, you will always have a
clean and regular configurational setup without the need to bother
with different starting points for configuring your project.

> Hmmmm, I need to give this a bit more thought -- any suggestions
> welcome...  Thank you!

Regards,

Michael
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Linking archives in a sibling directory

Raymond Wan
Hi Michael,

Thank you for the follow-up and sorry for my late response!  I
appreciate your suggestions as they basically summarize the problems
I've been having...


On Wed, Dec 8, 2010 at 21:25, Michael Hertling <[hidden email]> wrote:
> Yes, absolutely, with such relations among executables and libraries,
> their source directories should be siblings instead of descendants, and
> the libraries' testing executables can be conveniently integrated using
> ADD_TEST() without interfering with the main executables. However, when
> your project grows and, hence, the number of source directories in the
> project's root increases, say 10+, you should consider to organize them
> further, e.g. like


For example, I've reached around 10 source directories when I posted
my first message to the mailing list a couple of weeks back.  I
probably should have thought how to organize everything when I first
started -- but at least I'm thinking about it now instead of "much"
later!


> or whichever organizational criteria apply best, so the root directory
> doesn't fill with countless source directories. Apart from that, there
> is no need to have the top-level CMakeLists.txt create the main{1,2,3}
> executables by itself; just add a CMakeLists.txt file in each of their
> source directories as you do for the libraries, and use
>
> ADD_SUBDIRECTORY(main1)
> ADD_SUBDIRECTORY(main2)
> ADD_SUBDIRECTORY(main3)
>
> at the top level to enable them. In this way, you've a CMakeLists.txt
> file in each of your project's source directories which does exactly
> what needs to be done there, and the whole project is covered by the
> top-level CMakeLists.txt with minimal assumptions w.r.t. the source
> directories.


I see.  That makes sense to me; thank you!


> IMO, there is no reason to configure with lower-level CMakeLists.txt
> files at first and switch to a top-level CMakeLists.txt later. Instead,
> start right away with one CMakeLists.txt file per source directory and
> one top-level CMakeLists.txt, and whenever a new source directory with
> its own CMakeLists.txt is added to your project, just add an according
> ADD_SUBDIRECTORY() at the top level, too. So, you will always have a
> clean and regular configurational setup without the need to bother
> with different starting points for configuring your project.


Ok -- thank you for this; I'll definitely take your advice!

Thank you for your suggestions; I realize my question wasn't directly
related to CMake syntax and more generally to how to use CMake
properly for a project of this size.  Thank you for taking the time to
explain it to me; hopefully it has benefited others as well!

Ray
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake