[CMake] Chicken and egg problem with cmake_minimum_required(...), project(...), and CMAKE_SYSTEM_NAME

Alan W. Irwin irwin at beluga.phys.uvic.ca
Fri May 15 14:26:02 EDT 2015


On 2015-05-01 08:47-0400 Brad King wrote:

> On 05/01/2015 06:25 AM, Alan W. Irwin wrote:
>> # First call to project so that CMAKE_SYSTEM_NAME is defined
>> project(plplot NONE)
>> if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
>>      cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
>> else(CMAKE_SYSTEM_NAME STREQUAL "Linux")
>>      cmake_minimum_required(VERSION 3.2.2 FATAL_ERROR)
>> endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
>> # "Real" call to project
>> project(plplot C)
>
> You don't need another project().  You can use enable_language(C).
> Others have advised against having a different minimum, but if
> you have good reasons for it then:
>
> cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
> project(plplot NONE)
> if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
>   cmake_minimum_required(VERSION 3.2.2 FATAL_ERROR)
> endif()
> enable_language(C)
>
> Note that this will cause policy settings to differ on Linux
> versus elsewhere.

One further issue.  The maximum version of CMake that is packaged
for Cygwin is 3.1.2 so the 3.2 permissions fix for file(GENERATE...) is not available on
Cygwin yet (unless you build your own version of CMake there).

Thus, our actual current use case is we want to support older CMake
versions on both Linux and Cygwin, and I also want to include some
logic to make us use the same policies regardless of the choice of
minimum version.  So our logic attempted to follow what you suggest
above but ended up as follows:

##########################
function(plplot_cmake_minimum_required)
   cmake_minimum_required(${ARGV})

   # MAINTENANCE
   # This should be one more than the maximum policy of 3.0.2.
   set(minimum_old_policy 51)
   # This should be the maximum policy of 3.2.2
   set(maximum_old_policy 56)
   foreach(policy RANGE ${minimum_old_policy} ${maximum_old_policy})
     if(POLICY CMP00${policy})
       message(STATUS "Explicitly setting policy CMP00${policy} to OLD")
       cmake_policy(SET CMP00${policy} OLD)
     endif(POLICY CMP00${policy})
   endforeach(policy RANGE ${minimum_old_policy} ${maximum_old_policy})

endfunction(plplot_cmake_minimum_required)

plplot_cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(plplot NONE)
if(NOT (CYGWIN OR CMAKE_SYSTEM_NAME STREQUAL "Linux") )
   plplot_cmake_minimum_required(VERSION 3.2.2 FATAL_ERROR)
endif(NOT (CYGWIN OR CMAKE_SYSTEM_NAME STREQUAL "Linux") )
enable_language(C)

message(STATUS "CMake version = ${CMAKE_VERSION}")
message(STATUS "CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}")
##########################

This works fine on Linux, but I have a second-hand report this
generates the spurious warning on Cygwin (our last instance of this
spurious warning so I would really like to get rid of it!):

"CMake Warning at
/usr/share/cmake-3.1.2/Modules/Platform/CYGWIN.cmake:15 (message):
  CMake no longer defines WIN32 on Cygwin!
  [...]"

>From various experiments the reporter of this issue has found that
the problem is with the function command itself which apparently
cannot occur (on Cygwin) before cmake_minimum_required is called.

In fact, he simplified the problem down to this 4-line test:

function(plplot_cmake_minimum_required)
    cmake_minimum_required(${ARGV})
endfunction(plplot_cmake_minimum_required)
plplot_cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)

which generates the spurious warning on Cygwin while the single-line test,

cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)

(as expected) does not.

Can you confirm with your own experiments using the above 4-line test
on Cygwin that a function should not be used in this situation? Or is
there some CMake bug on Cygwin that is generating the spurious error
message?

In any case to work around this issue I am thinking of adjusting our
above PLplot build system logic as follows:

##########################
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)

function(set_plplot_policies)

   # MAINTENANCE
   # This should be one more than the maximum policy of 3.0.2.
   set(minimum_old_policy 51)
   # This should be the maximum policy of 3.2.2
   set(maximum_old_policy 56)
   foreach(policy RANGE ${minimum_old_policy} ${maximum_old_policy})
     if(POLICY CMP00${policy})
       message(STATUS "Explicitly setting policy CMP00${policy} to OLD")
       cmake_policy(SET CMP00${policy} OLD)
     endif(POLICY CMP00${policy})
   endforeach(policy RANGE ${minimum_old_policy} ${maximum_old_policy})

endfunction(set_plplot_policies)

project(plplot NONE)
set_plplot_polices()
if(NOT (CYGWIN OR CMAKE_SYSTEM_NAME STREQUAL "Linux") )
   cmake_minimum_required(VERSION 3.2.2 FATAL_ERROR)
   set_plplot_polices()
endif(NOT (CYGWIN OR CMAKE_SYSTEM_NAME STREQUAL "Linux") )
enable_language(C)

message(STATUS "CMake version = ${CMAKE_VERSION}")
message(STATUS "CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}")
##########################

Do you think this is a safe way (i.e., no more spurious Cygwin
warnings) to implement platform-dependent minimum versions or is there
some better approach I should be taking?

Alan
__________________________
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net); the Time
Ephemerides project (timeephem.sf.net); PLplot scientific plotting
software package (plplot.sf.net); the libLASi project
(unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
and the Linux Brochure Project (lbproject.sf.net).
__________________________

Linux-powered Science
__________________________


More information about the CMake mailing list