[CMake] Linking archives in a sibling directory

Michael Hertling mhertling at online.de
Wed Dec 8 07:25:33 EST 2010


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 <mhertling at online.de> 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


More information about the CMake mailing list