Forcing a target to be built if another target is built

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

Forcing a target to be built if another target is built

Job Noorman
Hi all,

We have a large codebase consisting of 200+ modules. Each module is
defined in its own subdirectory and compiled as a static library.

These modules are not final products on their own but are combined to
create "projects". We have about 15 projects that all use a subset of
the modules to implement their functionality. The projects are
independent in the sense that they cannot be built together; when
running cmake, we select the project to build.

To ensure that only the modules that are needed by the selected project
are built, we took the following approach: all modules have a common
root directory which is included using add_subdirectory with the
EXCLUDE_FROM_ALL flag. Then, the current project's root directory is
added without this flag. This ensures that the targets defined by the
project and the modules that they need (but no other) are added to the
build system. This works very well and is much nicer than having to
define options for all optional modules to be able to disable them.

There is one catch, however: each module defines an executable that runs
its unit tests. What should happen is that if a module is built by a
project, its unit tests are also built. However, there seems to be no
way to define this relationship in CMake. What we would like to express
is that "if library A is built, then executable ATest should also be
built". Since ATest obviously links against A, we cannot use
add_dependencies(A ATest) since this creates a circular dependency
between an executable and a library.

Note that the "option" approach briefly mentioned above would allow us
to express this but this would be completely unwieldy in our case.

Is there currently a way in CMake to express this relation between a
library and an executable?

If not, would the following suggestion make sense?: A target property
"INTERFACE_DEPENDENCIES" could be added that would set the
MANUALLY_ADDED_DEPENDENCIES target property of dependents. Setting this
property on A with ATest as value would then solve my problem (note that
I proposed adding this property for a different use case here:
https://gitlab.kitware.com/cmake/cmake/issues/14633).

Regards,
Job

--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

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

Re: Forcing a target to be built if another target is built

Robert Maynard

Have you thought about not doing anything in the root CMakeLists for your testing directories but instead inside the active project you use add_subdirectory ( it supports relative paths to handle directories not physically nested inside it ). 

On Wed, May 9, 2018 at 8:56 AM Job Noorman <[hidden email]> wrote:
Hi all,

We have a large codebase consisting of 200+ modules. Each module is
defined in its own subdirectory and compiled as a static library.

These modules are not final products on their own but are combined to
create "projects". We have about 15 projects that all use a subset of
the modules to implement their functionality. The projects are
independent in the sense that they cannot be built together; when
running cmake, we select the project to build.

To ensure that only the modules that are needed by the selected project
are built, we took the following approach: all modules have a common
root directory which is included using add_subdirectory with the
EXCLUDE_FROM_ALL flag. Then, the current project's root directory is
added without this flag. This ensures that the targets defined by the
project and the modules that they need (but no other) are added to the
build system. This works very well and is much nicer than having to
define options for all optional modules to be able to disable them.

There is one catch, however: each module defines an executable that runs
its unit tests. What should happen is that if a module is built by a
project, its unit tests are also built. However, there seems to be no
way to define this relationship in CMake. What we would like to express
is that "if library A is built, then executable ATest should also be
built". Since ATest obviously links against A, we cannot use
add_dependencies(A ATest) since this creates a circular dependency
between an executable and a library.

Note that the "option" approach briefly mentioned above would allow us
to express this but this would be completely unwieldy in our case.

Is there currently a way in CMake to express this relation between a
library and an executable?

If not, would the following suggestion make sense?: A target property
"INTERFACE_DEPENDENCIES" could be added that would set the
MANUALLY_ADDED_DEPENDENCIES target property of dependents. Setting this
property on A with ATest as value would then solve my problem (note that
I proposed adding this property for a different use case here:
https://gitlab.kitware.com/cmake/cmake/issues/14633).

Regards,
Job

--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

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

--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

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

Re: Forcing a target to be built if another target is built

Job Noorman
I'm not sure I completely understand what you mean but I think your
suggestion would be to list *all* needed subdirectories in the active
project. This is not what a want. The active project simply lists its
*direct* dependencies (via target_link_libraries) and CMake then figures
out all the needed transitive dependencies.

Please correct me if i missed your point :-)


On 15/05/18 23:29, Robert Maynard wrote:

>
> Have you thought about not doing anything in the root CMakeLists for
> your testing directories but instead inside the active project you use
> add_subdirectory ( it supports relative paths to handle directories
> not physically nested inside it ).
>
> On Wed, May 9, 2018 at 8:56 AM Job Noorman <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hi all,
>
>     We have a large codebase consisting of 200+ modules. Each module is
>     defined in its own subdirectory and compiled as a static library.
>
>     These modules are not final products on their own but are combined to
>     create "projects". We have about 15 projects that all use a subset of
>     the modules to implement their functionality. The projects are
>     independent in the sense that they cannot be built together; when
>     running cmake, we select the project to build.
>
>     To ensure that only the modules that are needed by the selected
>     project
>     are built, we took the following approach: all modules have a common
>     root directory which is included using add_subdirectory with the
>     EXCLUDE_FROM_ALL flag. Then, the current project's root directory is
>     added without this flag. This ensures that the targets defined by the
>     project and the modules that they need (but no other) are added to
>     the
>     build system. This works very well and is much nicer than having to
>     define options for all optional modules to be able to disable them.
>
>     There is one catch, however: each module defines an executable
>     that runs
>     its unit tests. What should happen is that if a module is built by a
>     project, its unit tests are also built. However, there seems to be no
>     way to define this relationship in CMake. What we would like to
>     express
>     is that "if library A is built, then executable ATest should also be
>     built". Since ATest obviously links against A, we cannot use
>     add_dependencies(A ATest) since this creates a circular dependency
>     between an executable and a library.
>
>     Note that the "option" approach briefly mentioned above would
>     allow us
>     to express this but this would be completely unwieldy in our case.
>
>     Is there currently a way in CMake to express this relation between a
>     library and an executable?
>
>     If not, would the following suggestion make sense?: A target property
>     "INTERFACE_DEPENDENCIES" could be added that would set the
>     MANUALLY_ADDED_DEPENDENCIES target property of dependents. Setting
>     this
>     property on A with ATest as value would then solve my problem
>     (note that
>     I proposed adding this property for a different use case here:
>     https://gitlab.kitware.com/cmake/cmake/issues/14633).
>
>     Regards,
>     Job
>
>     --
>
>     Powered by www.kitware.com <http://www.kitware.com>
>
>     Please keep messages on-topic and check the CMake FAQ at:
>     http://www.cmake.org/Wiki/CMake_FAQ
>
>     Kitware offers various services to support the CMake community.
>     For more information on each offering, please visit:
>
>     CMake Support: http://cmake.org/cmake/help/support.html
>     CMake Consulting: http://cmake.org/cmake/help/consulting.html
>     CMake Training Courses: http://cmake.org/cmake/help/training.html
>
>     Visit other Kitware open-source projects at
>     http://www.kitware.com/opensource/opensource.html
>
>     Follow this link to subscribe/unsubscribe:
>     https://cmake.org/mailman/listinfo/cmake
>

--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

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

Re: Forcing a target to be built if another target is built

Robert Maynard
That is roughly what I am saying. In my head you had a layout that looked like

-> root_dir
--> module_A
--> tests_A
--> module_B
--> tests_B

So while it is tedious to have module_A explicitly add tests_A it would be a possible solution. The problem is one of graph building.  Currently the CMake 'all' graph properly represents building the active module and all dependencies it needs. Separately you have a pool of smaller graphs that represent all tests and targets that are from sub-directories that had EXCLUDE_FROM_ALL applied. Nothing is quickly coming to me that will allow you to add more components to the 'all' graph after the fact.

On Thu, May 17, 2018 at 6:19 AM Job Noorman <[hidden email]> wrote:
I'm not sure I completely understand what you mean but I think your
suggestion would be to list *all* needed subdirectories in the active
project. This is not what a want. The active project simply lists its
*direct* dependencies (via target_link_libraries) and CMake then figures
out all the needed transitive dependencies.

Please correct me if i missed your point :-)


On 15/05/18 23:29, Robert Maynard wrote:
>
> Have you thought about not doing anything in the root CMakeLists for
> your testing directories but instead inside the active project you use
> add_subdirectory ( it supports relative paths to handle directories
> not physically nested inside it ).
>
> On Wed, May 9, 2018 at 8:56 AM Job Noorman <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hi all,
>
>     We have a large codebase consisting of 200+ modules. Each module is
>     defined in its own subdirectory and compiled as a static library.
>
>     These modules are not final products on their own but are combined to
>     create "projects". We have about 15 projects that all use a subset of
>     the modules to implement their functionality. The projects are
>     independent in the sense that they cannot be built together; when
>     running cmake, we select the project to build.
>
>     To ensure that only the modules that are needed by the selected
>     project
>     are built, we took the following approach: all modules have a common
>     root directory which is included using add_subdirectory with the
>     EXCLUDE_FROM_ALL flag. Then, the current project's root directory is
>     added without this flag. This ensures that the targets defined by the
>     project and the modules that they need (but no other) are added to
>     the
>     build system. This works very well and is much nicer than having to
>     define options for all optional modules to be able to disable them.
>
>     There is one catch, however: each module defines an executable
>     that runs
>     its unit tests. What should happen is that if a module is built by a
>     project, its unit tests are also built. However, there seems to be no
>     way to define this relationship in CMake. What we would like to
>     express
>     is that "if library A is built, then executable ATest should also be
>     built". Since ATest obviously links against A, we cannot use
>     add_dependencies(A ATest) since this creates a circular dependency
>     between an executable and a library.
>
>     Note that the "option" approach briefly mentioned above would
>     allow us
>     to express this but this would be completely unwieldy in our case.
>
>     Is there currently a way in CMake to express this relation between a
>     library and an executable?
>
>     If not, would the following suggestion make sense?: A target property
>     "INTERFACE_DEPENDENCIES" could be added that would set the
>     MANUALLY_ADDED_DEPENDENCIES target property of dependents. Setting
>     this
>     property on A with ATest as value would then solve my problem
>     (note that
>     I proposed adding this property for a different use case here:
>     https://gitlab.kitware.com/cmake/cmake/issues/14633).
>
>     Regards,
>     Job
>
>     --
>
>     Powered by www.kitware.com <http://www.kitware.com>
>
>     Please keep messages on-topic and check the CMake FAQ at:
>     http://www.cmake.org/Wiki/CMake_FAQ
>
>     Kitware offers various services to support the CMake community.
>     For more information on each offering, please visit:
>
>     CMake Support: http://cmake.org/cmake/help/support.html
>     CMake Consulting: http://cmake.org/cmake/help/consulting.html
>     CMake Training Courses: http://cmake.org/cmake/help/training.html
>
>     Visit other Kitware open-source projects at
>     http://www.kitware.com/opensource/opensource.html
>
>     Follow this link to subscribe/unsubscribe:
>     https://cmake.org/mailman/listinfo/cmake
>


--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

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