[CMake] Linking archives in a sibling directory

Raymond Wan r.wan at aist.go.jp
Fri Dec 3 10:26:37 EST 2010


Hi Michael,

Thank you for your continued advice!


On Fri, Dec 3, 2010 at 19:13, Michael Hertling <mhertling at online.de> 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


More information about the CMake mailing list