modularizing, specifying dependencies in a project

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

modularizing, specifying dependencies in a project

Geogin Varghese
Hello,

Recently came across these presentations on cmake:

Using Modern CMake Patterns to Enforce a Good Modular Design
(https://www.youtube.com/watch?v=bsXLMQ6WgIk)
Effective CMake
(https://www.youtube.com/watch?v=eC9-iRN2b04)

They encourage using target_* command variants for scripting
CMakeLists.txt.

What would be the recommended way of writing build scripts for a
repository structured as below. The application is compiled from three
modules with a dependency among the modules as in the ascii diagram.

Is it possible to distribute compile info, such that each submodule has
a CMakeLists.txt that describes sources, include and link dependencies needed
to compile that module.

---------------------------------------
.
├── main.cpp
├── ModA
├── ModB
├── ModC

Dependency relation:
--------------------
       +--------+
    +->+main.cpp+<-+
    |  +--------+  |
    |              |
    |              |
    |              |
  +----+        +----+
  |ModA|        |ModB|
  +----+        +----+
    ^              ^
    |              |
    |    +----+    |
    +----+ModC+----+
         +----+

ModA <- ModC: Module A
 depends on Module C
---------------------------------------

My naive effort to do this can be found here:
https://github.com/vargheseg/test

The problem I run into is with describing the dependency relation
between ModA, ModB and ModC.

Details:
.
├── CMakeLists.txt
├── main.cpp
├── ModA
│   ├── a.cpp
│   └── CMakeLists.txt
├── ModB
│   ├── b.cpp
│   └── CMakeLists.txt
├── ModC
│   ├── c.cpp
│   └── CMakeLists.txt

- CMakeLists.txt in the child directories describe compilation
  information for that directory.
- The top level directory includes the CMakeLists.txt from
  subdirectories.
- Cmake buildfile generation fails because the way I set things up; the
  top level CMakeLists.txt ends up including ModC/CMakeLists.txt twice.

---
CMakeLists.txt
---
 cmake_minimum_required(VERSION 3.0)
 project(test_project)

 include(${CMAKE_CURRENT_LIST_DIR}/ModA/CMakeLists.txt)
 include(${CMAKE_CURRENT_LIST_DIR}/ModB/CMakeLists.txt)

 add_executable(main main.cpp)
 target_link_libraries(main PRIVATE ModA ModB)


---
ModA/CMakeLists.txt
---
 include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
 add_library(ModA  $CMAKE_CURRENT_LIST_DIR}/a.cpp)
 target_link_libraries(ModA PRIVATE ModC)


---
ModB/CMakeLists.txt
---
 include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
 add_library(ModB b.cpp)
 target_link_libraries(ModB
         PRIVATE
         ModC)

Is this way of structuring a project a supported use case?
--

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: modularizing, specifying dependencies in a project

Robert Maynard
You will want to use add_subdirectory instead of include in the root
CMakeLists.txt and remove all include statements from ModA and ModB

It total the changes needed to get everything to work are:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e611a37..b6968c1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,8 +1,9 @@
 cmake_minimum_required(VERSION 3.0)
 project(test_project)

-include(${CMAKE_CURRENT_LIST_DIR}/ModA/CMakeLists.txt)
-include(${CMAKE_CURRENT_LIST_DIR}/ModB/CMakeLists.txt)
+add_subdirectory(ModA)
+add_subdirectory(ModB)
+add_subdirectory(ModC)

 add_executable(main main.cpp)
 target_link_libraries(main
diff --git a/ModA/CMakeLists.txt b/ModA/CMakeLists.txt
index 87128d8..4931be6 100644
--- a/ModA/CMakeLists.txt
+++ b/ModA/CMakeLists.txt
@@ -1,5 +1,4 @@
-include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
-add_library(ModA  $CMAKE_CURRENT_LIST_DIR}/a.cpp)
+add_library(ModA a.cpp)
 target_link_libraries(ModA
        PRIVATE
          ModC)
diff --git a/ModB/CMakeLists.txt b/ModB/CMakeLists.txt
index 3a31be9..7f83856 100644
--- a/ModB/CMakeLists.txt
+++ b/ModB/CMakeLists.txt
@@ -1,4 +1,3 @@
-include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)

 add_library(ModB b.cpp)
 target_link_libraries(ModB

On Wed, Jan 3, 2018 at 1:46 PM, Geogin Varghese <[hidden email]> wrote:

> Hello,
>
> Recently came across these presentations on cmake:
>
> Using Modern CMake Patterns to Enforce a Good Modular Design
> (https://www.youtube.com/watch?v=bsXLMQ6WgIk)
> Effective CMake
> (https://www.youtube.com/watch?v=eC9-iRN2b04)
>
> They encourage using target_* command variants for scripting
> CMakeLists.txt.
>
> What would be the recommended way of writing build scripts for a
> repository structured as below. The application is compiled from three
> modules with a dependency among the modules as in the ascii diagram.
>
> Is it possible to distribute compile info, such that each submodule has
> a CMakeLists.txt that describes sources, include and link dependencies needed
> to compile that module.
>
> ---------------------------------------
> .
> ├── main.cpp
> ├── ModA
> ├── ModB
> ├── ModC
>
> Dependency relation:
> --------------------
>        +--------+
>     +->+main.cpp+<-+
>     |  +--------+  |
>     |              |
>     |              |
>     |              |
>   +----+        +----+
>   |ModA|        |ModB|
>   +----+        +----+
>     ^              ^
>     |              |
>     |    +----+    |
>     +----+ModC+----+
>          +----+
>
> ModA <- ModC: Module A
>  depends on Module C
> ---------------------------------------
>
> My naive effort to do this can be found here:
> https://github.com/vargheseg/test
>
> The problem I run into is with describing the dependency relation
> between ModA, ModB and ModC.
>
> Details:
> .
> ├── CMakeLists.txt
> ├── main.cpp
> ├── ModA
> │   ├── a.cpp
> │   └── CMakeLists.txt
> ├── ModB
> │   ├── b.cpp
> │   └── CMakeLists.txt
> ├── ModC
> │   ├── c.cpp
> │   └── CMakeLists.txt
>
> - CMakeLists.txt in the child directories describe compilation
>   information for that directory.
> - The top level directory includes the CMakeLists.txt from
>   subdirectories.
> - Cmake buildfile generation fails because the way I set things up; the
>   top level CMakeLists.txt ends up including ModC/CMakeLists.txt twice.
>
> ---
> CMakeLists.txt
> ---
>  cmake_minimum_required(VERSION 3.0)
>  project(test_project)
>
>  include(${CMAKE_CURRENT_LIST_DIR}/ModA/CMakeLists.txt)
>  include(${CMAKE_CURRENT_LIST_DIR}/ModB/CMakeLists.txt)
>
>  add_executable(main main.cpp)
>  target_link_libraries(main PRIVATE ModA ModB)
>
>
> ---
> ModA/CMakeLists.txt
> ---
>  include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
>  add_library(ModA  $CMAKE_CURRENT_LIST_DIR}/a.cpp)
>  target_link_libraries(ModA PRIVATE ModC)
>
>
> ---
> ModB/CMakeLists.txt
> ---
>  include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
>  add_library(ModB b.cpp)
>  target_link_libraries(ModB
>          PRIVATE
>          ModC)
>
> Is this way of structuring a project a supported use case?
> --
>
> 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: modularizing, specifying dependencies in a project

Geogin Varghese
In reply to this post by Geogin Varghese
This works.

Have pushed changes to the repo here:
https://github.com/vargheseg/test

Thank you

On Wed, Jan 3, 2018 at 8:16 PM, Robert Maynard
<[hidden email]> wrote:

> You will want to use add_subdirectory instead of include in the root
> CMakeLists.txt and remove all include statements from ModA and ModB
>
> It total the changes needed to get everything to work are:
>
> diff --git a/CMakeLists.txt b/CMakeLists.txt
> index e611a37..b6968c1 100644
> --- a/CMakeLists.txt
> +++ b/CMakeLists.txt
> @@ -1,8 +1,9 @@
>  cmake_minimum_required(VERSION 3.0)
>  project(test_project)
>
> -include(${CMAKE_CURRENT_LIST_DIR}/ModA/CMakeLists.txt)
> -include(${CMAKE_CURRENT_LIST_DIR}/ModB/CMakeLists.txt)
> +add_subdirectory(ModA)
> +add_subdirectory(ModB)
> +add_subdirectory(ModC)
>
>  add_executable(main main.cpp)
>  target_link_libraries(main
> diff --git a/ModA/CMakeLists.txt b/ModA/CMakeLists.txt
> index 87128d8..4931be6 100644
> --- a/ModA/CMakeLists.txt
> +++ b/ModA/CMakeLists.txt
> @@ -1,5 +1,4 @@
> -include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
> -add_library(ModA  $CMAKE_CURRENT_LIST_DIR}/a.cpp)
> +add_library(ModA a.cpp)
>  target_link_libraries(ModA
>         PRIVATE
>           ModC)
> diff --git a/ModB/CMakeLists.txt b/ModB/CMakeLists.txt
> index 3a31be9..7f83856 100644
> --- a/ModB/CMakeLists.txt
> +++ b/ModB/CMakeLists.txt
> @@ -1,4 +1,3 @@
> -include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
>
>  add_library(ModB b.cpp)
>  target_link_libraries(ModB
>
> On Wed, Jan 3, 2018 at 1:46 PM, Geogin Varghese <[hidden email]> wrote:
>> Hello,
>>
>> Recently came across these presentations on cmake:
>>
>> Using Modern CMake Patterns to Enforce a Good Modular Design
>> (https://www.youtube.com/watch?v=bsXLMQ6WgIk)
>> Effective CMake
>> (https://www.youtube.com/watch?v=eC9-iRN2b04)
>>
>> They encourage using target_* command variants for scripting
>> CMakeLists.txt.
>>
>> What would be the recommended way of writing build scripts for a
>> repository structured as below. The application is compiled from three
>> modules with a dependency among the modules as in the ascii diagram.
>>
>> Is it possible to distribute compile info, such that each submodule has
>> a CMakeLists.txt that describes sources, include and link dependencies needed
>> to compile that module.
>>
>> ---------------------------------------
>> .
>> ├── main.cpp
>> ├── ModA
>> ├── ModB
>> ├── ModC
>>
>> Dependency relation:
>> --------------------
>>        +--------+
>>     +->+main.cpp+<-+
>>     |  +--------+  |
>>     |              |
>>     |              |
>>     |              |
>>   +----+        +----+
>>   |ModA|        |ModB|
>>   +----+        +----+
>>     ^              ^
>>     |              |
>>     |    +----+    |
>>     +----+ModC+----+
>>          +----+
>>
>> ModA <- ModC: Module A
>>  depends on Module C
>> ---------------------------------------
>>
>> My naive effort to do this can be found here:
>> https://github.com/vargheseg/test
>>
>> The problem I run into is with describing the dependency relation
>> between ModA, ModB and ModC.
>>
>> Details:
>> .
>> ├── CMakeLists.txt
>> ├── main.cpp
>> ├── ModA
>> │   ├── a.cpp
>> │   └── CMakeLists.txt
>> ├── ModB
>> │   ├── b.cpp
>> │   └── CMakeLists.txt
>> ├── ModC
>> │   ├── c.cpp
>> │   └── CMakeLists.txt
>>
>> - CMakeLists.txt in the child directories describe compilation
>>   information for that directory.
>> - The top level directory includes the CMakeLists.txt from
>>   subdirectories.
>> - Cmake buildfile generation fails because the way I set things up; the
>>   top level CMakeLists.txt ends up including ModC/CMakeLists.txt twice.
>>
>> ---
>> CMakeLists.txt
>> ---
>>  cmake_minimum_required(VERSION 3.0)
>>  project(test_project)
>>
>>  include(${CMAKE_CURRENT_LIST_DIR}/ModA/CMakeLists.txt)
>>  include(${CMAKE_CURRENT_LIST_DIR}/ModB/CMakeLists.txt)
>>
>>  add_executable(main main.cpp)
>>  target_link_libraries(main PRIVATE ModA ModB)
>>
>>
>> ---
>> ModA/CMakeLists.txt
>> ---
>>  include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
>>  add_library(ModA  $CMAKE_CURRENT_LIST_DIR}/a.cpp)
>>  target_link_libraries(ModA PRIVATE ModC)
>>
>>
>> ---
>> ModB/CMakeLists.txt
>> ---
>>  include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
>>  add_library(ModB b.cpp)
>>  target_link_libraries(ModB
>>          PRIVATE
>>          ModC)
>>
>> Is this way of structuring a project a supported use case?
>> --
>>
>> 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