[cmake-developers] COMPILE_FEATURES, Mac and non-Apple clang versions

Stephen Kelly steveire at gmail.com
Thu Jan 5 19:57:11 EST 2017


Craig Scott wrote:

>> if you use add_subdirectory with top-level projects which don't
>> explicitly do something like that, you're getting undefined , and
>> generally unexpected behavior in many ways.
> 
> This seems at odds with the CMake documentation for
> cmake_minimum_required(). That documentation talks about calling
> cmake_minimum_required() within a function as a valid case

I don't know why using that command inside a function would be a good idea.

What would you be trying to achieve with putting it in a function not near 
the top? Can you give an example?

> Yes, each one will alter the policy behaviour for that
> scope and below, but assuming that's what the project wanted to enforce,
> this should be fine.

I would expect that many users are surprised by the result of this. 
cmake_policy(VERSION) is probably better if you want to set policies.

[Aside: I happen to think that it would be better if the canonical start of 
a top CMakeLists file would be 

 cmake_policy(VERSION 3.2)
 project(foo)

Most users (especially non-power-users) don't realize the connection between 
cmake_minimum_required and policies and why that's important]

> We have many projects which do exactly the scenario you mention above
> where a project can be built standalone or added to another project via
> add_subdirectory(). We have not found it necessary to test if a project is
> top level or not before calling cmake_minimum_required(). 

My comment should have been more-general in that the contained project 
should be designed to be 'inlined as a subdirectory' like that and it 
otherwise shouldn't be done. 

There are many pitfalls. I have encountered at least one pitfall resulting 
from cmake_minimum_required being unconditional which I don't remember now 
unfortunately. Perhaps the problem was my inexperience to understand 
messages I was seeing and what I expected from the code.

Others include 

* conflicting target names
* conflicting option()s, or option()s which shouldn't be exposed
* modification of global or cache variables affecting the container project 
in unexpected ways such as modifying compile flags
* possibly odd behavior if you have multiple include(CTest) or 
include(CPack) in different directories
* projects which assume CMAKE_SOURCE_DIR is their top-level and use 
something like include($CMAKE_SOURCE_DIR}/cmake/MyPrivateMacros.cmake)
* deliberate checks for top-level in a file include()d in multiple locations 
in the project.

Sure, you can test things out when you add a new 
 
 add_subdirectory(random_github_clone)

but just because it works (enough! - do any of them use CMAKE_SOURCE_DIR and 
it doesn't cause *visible* problems?) with all of the external projects 
you've tried so far doesn't mean you can expect it to work with any external 
project. 

For me, that's as close as you get to 'undefined behavior' in CMake code.

Thanks,

Steve.




More information about the cmake-developers mailing list