[CMake] CMAKE_MFC_FLAG not working in functions

Michael Hertling mhertling at online.de
Thu Oct 20 13:56:29 EDT 2011


On 10/20/2011 06:59 PM, Robert Dailey wrote:
> Let me ask this,
> 
> What would be the parent of a function located in the root CMakeLists file
> but called from a subordinate CMakeLists file?

It's the subordinate CMakeLists.txt file's parent, but what Michael
probably aims at is that some variables undergo a lazy evaluation,
i.e. when you say

set( CMAKE_MFC_FLAG 2 )
add_executable( ... )

in a function, and CMAKE_MFC_FLAG isn't evaluated till generation time,
the value "2" will be lost since it is limited to the function's scope.
See the following project for an example:

# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LAZY C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FUNCTION(ADD_EXECUTABLE_LOCAL TARGET)
    SET(CMAKE_C_FLAGS "${CMAKE_FLAGS} -DLOCAL")
    ADD_EXECUTABLE(${TARGET} ${ARGN})
ENDFUNCTION()
FUNCTION(ADD_EXECUTABLE_PARENT TARGET)
    SET(CMAKE_C_FLAGS "${CMAKE_FLAGS} -DPARENT" PARENT_SCOPE)
    ADD_EXECUTABLE(${TARGET} ${ARGN})
ENDFUNCTION()
ADD_SUBDIRECTORY(local)
ADD_SUBDIRECTORY(parent)

# local/CMakeLists.txt:
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.c
    "int main(void){return 0;}\n")
ADD_EXECUTABLE_LOCAL(local main.c)

# parent/CMakeLists.txt:
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.c
    "int main(void){return 0;}\n")
ADD_EXECUTABLE_PARENT(parent main.c)

This should somewhat reflect the situation you reported. The sole
difference between the functions - besides the differently named
preprocessor definitions - is the PARENT_SCOPE flag. As you can
see, the "local" target is built without the -DLOCAL whereas the
"parent" target is built with the -DPARENT. This is because the
CMAKE_C_FLAGS in ADD_EXECUTABLE_LOCAL() isn't in effect anymore
at the end of local/CMakeLists.txt when the ADD_EXECUTABLE() is
actually used to generate the final build files, i.e. Makefiles,
Projects etc. In contrast, -DPARENT *is* in effect at the end
of parent/CMakeLists.txt when the build files are generated.

Regards,

Michael

> On Thu, Oct 20, 2011 at 11:55 AM, Michael Wild <themiwi at gmail.com> wrote:
> 
>> On 10/20/2011 05:41 PM, Robert Dailey wrote:
>>> On Thu, Oct 20, 2011 at 2:36 AM, Rolf Eike Beer <eike at sf-mail.de
>>> <mailto:eike at sf-mail.de>> wrote:
>>>
>>>     > I have a function defined very high up in the directory tree at
>>>     the root
>>>     > CMakeLists file. Several levels below it, I have another
>>>     CMakeLists file
>>>     > that I call that function from.
>>>     >
>>>     > The function sets CMAKE_MFC_FLAG to 2. I notice that this flag gets
>>>     > ignored
>>>     > when it is set inside of the function in question. If I set the
>> flag
>>>     > outside
>>>     > of the function, in the lowest level CMakeLists file, it works.
>> This
>>>     > property seems somehow tied to the directory itself, but I can't
>>>     figure
>>>     > out
>>>     > if this is a feature or a bug.
>>>     >
>>>     > This behavior isn't very flexible as I'd like to make the details
>> of
>>>     > configuring an MFC compatible project transparent to the lower
>> level
>>>     > CMakeLists scripts. Hiding away the flag and how it needs to be
>>>     set is a
>>>     > big
>>>     > part of this, but I can't do it.
>>>     >
>>>     > Anyone know how I can make this work?
>>>
>>>     A function creates a new variable scope, i.e. everything you set in
>>>     there
>>>     will be reset once you leave the function. Have a look at SET(...
>>>     PARENT_SCOPE) for this.
>>>
>>>
>>> Not even that worked, unfortunately.
>>>
>>> Basically from my function I do:
>>>
>>> set( CMAKE_MFC_FLAG 2 )
>>> add_executable( ... )
>>>
>>> Since I'm setting it right before the add_executable() call, I would
>>> think that scope has nothing to do with it.
>>
>> No, the add_executable() call does not evaluate the variable. It only
>> gets evaluated *after* the processing of the current CMakeLists.txt
>> file. If using set(CMAKE_MFC_FLAG 2 PARENT_SCOPE) really doesn't work,
>> IMHO that would be a bug. The only work-around would be to use a macro
>> instead (where you don't need the PARENT_SCOPE at all).
>>
>> Michael


More information about the CMake mailing list