[CMake] CMake command line arguments

Michael Hertling mhertling at online.de
Mon Mar 7 07:06:42 EST 2011


On 03/07/2011 12:37 PM, Gabriel Petrovay wrote:
> Thanks for the tips, Michael.
> 
> We will do so, using project specific BUILD_TYPE and INSTALL_PREFIX.

However, the downside of this approach is that your project's users
should not refer to the well-known CMake variables CMAKE_BUILD_TYPE
and CMAKE_INSTALL_PREFIX anymore - possibly an issue to consider.

> On Mon, Mar 7, 2011 at 12:20 PM, Michael Hertling <mhertling at online.de> wrote:
>> On 03/07/2011 11:33 AM, Michael Hertling wrote:
>>> On 03/06/2011 12:12 PM, Gabriel Petrovay wrote:
>>>> Hi,
>>>>
>>>> Is there a way to read the arguments that were passed to CMake from
>>>> inside a CMakeLists.txt file?
>>>>
>>>> There is a problem that some generators (like "NMake Makefiles") set a
>>>> default value for certain variables (like CMAKE_BUILD_TYPE=Debug,
>>>> CMAKE_INSTALL_PREFIX=C:\Program Files\${CMAKE_PROJECT_NAME})
>>>>
>>>> From inside CMake one can not set up a different default value if the
>>>> user does not specify it with a -D option. This is because
>>>> IF(CMAKE_BUILD_TYPE) will always be true because of the default set by
>>>> the generator ("NMake Makefiles").
>>>>
>>>> There was this guy having the same problem:
>>>> http://www.mail-archive.com/cmake@cmake.org/msg09640.html
>>>>
>>>> Any solution how one can solve this? Reading the arguments passed to
>>>> CMake would be one, but I find no documentation/example/google_result
>>>> for this.
>>>>
>>>>
>>>> Thanks!
>>>
>>> Scanning the command line for user-supplied settings wouldn't be
>>> reliable because your project might also be configured via a GUI.
>>>
>>> Furthermore, even an empty CMAKE_BUILD_TYPE variable may denote a
>>> valid build type, so there's no robust criterion to decide when to
>>> set a default value by examining this variable alone. Instead, you
>>> might use another variable, say ${PROJECT_NAME}_BUILD_TYPE, and do:
>>>
>>> IF(NOT DEFINED ${PROJECT_NAME}_BUILD_TYPE)
>>>     SET(${PROJECT_NAME}_BUILD_TYPE "CUSTOM")
>>> ENDIF()
>>> SET(CMAKE_BUILD_TYPE "${${PROJECT_NAME}_BUILD_TYPE}")
>>
>> Alternatively, you might do:
>>
>> SET(${PROJECT_NAME}_BUILD_TYPE "CUSTOM"
>>    CACHE STRING "${PROJECT_NAME} Build Type")
>> SET(CMAKE_BUILD_TYPE "${${PROJECT_NAME}_BUILD_TYPE}")
>>
>> So, you'll have at least your project's own build type in the cache -
>> and, thus, in the GUIs - along with the documenting comment while the
>> cached value of CMAKE_BUILD_TYPE is still not the one that's actually
>> used.

If you say

SET(CMAKE_BUILD_TYPE "${${PROJECT_NAME}_BUILD_TYPE}"
    CACHE STRING "CMake Build Type" FORCE)

here, the cached value of CMAKE_BUILD_TYPE will equal the value in the
current scope again. Obviously, I'm quite unconcentrated today... ;-)

>>> In this way, an undefined ${PROJECT_NAME}_BUILD_TYPE results in a
>>> default CMAKE_BUILD_TYPE on behalf of the CMakeLists.txt file. Of
>>> course, you should document that variable and urge your project's
>>> users to not directly use CMAKE_BUILD_TYPE anymore; perhaps, you
>>> should even hide the latter in a GUI by marking it as advanced.
>>>
>>> With regard to CMAKE_INSTALL_PREFIX, you could do the same - or use
>>> CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT, as a robust criterion,
>>> to see whether the user has supplied a value explicitly. Note that
>>> there're additional aspects to consider if the CMakeLists.txt file
>>> is to write that variable's value to the cache, cf. [1] et seq.
>>>
>>> Regards,
>>>
>>> Michael


More information about the CMake mailing list