Note that there are some explanatory texts on larger screens.

plurals
  1. POCMake add_subdirectory and recompiling
    primarykey
    data
    text
    <p>I've just migrated a somewhat large project from Visual Studio solutions to CMake and I've noticed a weird behavior. I have something like the following structure:</p> <pre><code>project/CMakeLists.txt project/code/CMakeLists.txt project/code/library-1/CMakeLists.txt project/code/library-1/*.hpp project/code/library-1/*.cpp project/code/library-2/CMakeLists.txt project/code/library-2/*.hpp project/code/library-2/*.cpp ... project/code/library-n/CMakeLists.txt project/code/library-n/*.hpp project/code/library-n/*.cpp project/demo/CMakeLists.txt project/demo/demo-1/CMakeLists.txt project/demo/demo-1/*.hpp project/demo/demo-1/*.cpp project/demo/demo-2/CMakeLists.txt project/demo/demo-2/*.hpp project/demo/demo-2/*.cpp ... project/demo/demo-n/CMakeLists.txt project/demo/demo-n/*.hpp project/demo/demo-n/*.cpp </code></pre> <ol> <li>The root <code>CMakeLists.txt</code> file configures the compilation flags, macro definitions, etc. and uses CMake's <code>add_subdirectory()</code> to include targets defined by the libraries and demo projects.</li> <li>The <code>code</code> sub-folder contains a flat list of sub-folders with each containing source code for a static library (as well as its target defined in a <code>CMakeLists.txt</code> file).</li> <li>The <code>demo</code> sub-folder contains a flat list of sub-folders. Each contains source code for an executable and associated <code>CMakeLists.txt</code> file.</li> <li>Each library is a standalone component and builds independently from all other libraries and demo projects.</li> <li>Each demo program depends on one or more of the different libraries in the <code>code</code> sub-folder.</li> </ol> <p>This setup is really nice. If I want to change build options, I only need to modify the root <code>CMakeLists.txt</code> and everything re-compiles with the new settings. If I modify any source code anywhere in the tree, the appropriate libraries, if any, are recompiled and all dependent demo programs are also re-built.</p> <p>However, if I modify <em>any</em> <code>CMakeLists.txt</code> file anywhere in the tree, the entire tree of libraries and programs is re-compiled without respect of dependencies. To give an idea of what I mean, here a few parts of the CMake build scripts.</p> <hr> <p><strong><code>project/demo/CMakeLists.txt</code></strong></p> <pre><code># Resolve libraries built in `code` sub-folder. link_directories(${LIBRARY_OUTPUT_PATH}) set(demo-projects demo-1 demo-2 ... demo-n ) foreach(demo-project ${demo-projects}) add_subdirectory(${demo-project}) endforeach() </code></pre> <hr> <p><strong><code>project/demo/demo-n/CMakeLists.txt</code></strong></p> <pre><code># Find all source code in the same folder. file(GLOB ${demo-project}_headers ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp ) file(GLOB ${demo-project}_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) # Select libraries to link with. set(${demo-project}_libraries library-1 library-2 library-5 ) # Build the demo program. add_executable(${demo-project} ${${demo-project}_headers} ${${demo-project}_sources} ) if(${demo-project}_libraries) target_link_libraries(${demo-project} ${${demo-project}_libraries}) endif() # Manually register some dependencies on other targets. if(${demo-project}_dependencies) add_dependencies(${demo-project} ${${demo-project}_dependencies}) endif() </code></pre> <hr> <p>If I happen to modify <code>project/demo/demo-n/CMakeLists.txt</code> to add an extra library, like this:</p> <pre><code>set(${demo-project}_libraries library-1 library-2 library-5 library-6 ) </code></pre> <p>Then the <em>entire</em> source code for all libraries and demo programs in the project is re-compiled. Why is this so? Is there a better way to structure my scripts in order to avoid this?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload