[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