title: Best practices with CMake, `CMAKE_CXX_STANDARD`, and the cache?
body: <p>I'm working on a large C++ library, with CMake targeting <a href="https://www.gnu.org/software/make/" rel="nofollow noreferrer">GNU make</a> and building into a <code>_build/</code> directory. The top level <code>CMakeLists.txt</code> uses <code>list(APPEND as_subproject ...)</code> to add a number of third party projects. A simple <code>Makefile</code> at the top level makes initiating builds easier and more consistent. The <code>Makefile</code> has two targets:</p>
  <ul>
  <li><code>make clean</code>: runs <code>make -C _build clean</code> and then deletes the <code>_build</code> directory</li>
  <li><code>make all</code>: deletes <code>_build/CMakeCache.txt</code>, runs CMake to generate the Makefiles in the <code>_build</code> directory, and then runs <code>make -C _build all</code> to do the actual build.</li>
  </ul>
  <p>This has worked fairly well, until an update to one of the third party projects added the following line to their CMakeLists.txt:</p>
  <pre><code>set(CMAKE_CXX_STANDARD 11 CACHE STRING &quot;Default value for CXX_STANDARD property of targets&quot;)
  </code></pre>
  <p>This broke our build, because every Makefile generated <strong>after</strong> this submodule now restricts compilation to C++11. I understand the authors' intent: if the parent project doesn't set the cached value of <code>CMAKE_CXX_STANDARD</code>, then the library sets it to &quot;11&quot;, but otherwise it's left alone. But, now we have my library components building differently based on whether they are built before or after this project, which is way too weird for comfort.</p>
  <p>Which brings me to my question: how should I specify my <code>make all</code> behavior? Some choices, all of which give me the heebie-jeebies:</p>
  <ul>
  <li>Continue to delete <code>_build/CMakeCache.txt</code> at the beginning of every <code>make all</code>, so I'll get the same build every time. Problem: the C++ standards enforced will be different depending on the order that the <code>Makefile</code>s are generated.</li>
  <li>Do not delete <code>_build/CMakeCache.txt</code> at the beginning of <code>make all</code>. Problem: the first build after a clean will be different from all subsequent builds.</li>
  <li>Have my top level <code>CMakeLists.txt</code> set <code>CMAKE_CXX_STANDARD</code> in the cache, which would make my builds consistent. Problem 1: I'm passing the buck to whomever uses my library. Problem 2: someday, some submodule will set some other value in the cache, starting the arms race all over again.</li>
  </ul>
  <p>What's the right way to handle this?</p>