0

CMake variables management is driving me nuts....

I'd like to call a function, who calls another function in order to modify a variable that will end up to be the content of a file to be written.

It looks like this:

function( QMAKE_ADD_LINE_TO_VAR var line )
  set( ${var} "${${var}}\n${line}\n" PARENT_SCOPE )
endfunction()

function( QMAKE_ADD_RELEASE_AND_DEBUG_LINES_TO_VAR var relline debugline )
   QMAKE_ADD_LINE_TO_VAR( ${var} "release:${relline} (two functions call)" )
   QMAKE_ADD_LINE_TO_VAR( ${var} "debug:${debugline} (two functions call)" )
endfunction()

QMAKE_ADD_LINE_TO_VAR(FILE_CONTENT "#Generated by CMake scripts!")
QMAKE_ADD_RELEASE_AND_DEBUG_LINES_TO_VAR( FILE_CONTENT "foo" "bar" )
QMAKE_ADD_LINE_TO_VAR( FILE_CONTENT "release:foo (single function call)" )
QMAKE_ADD_LINE_TO_VAR( FILE_CONTENT "debug:bar (single function call)" )
QMAKE_ADD_LINE_TO_VAR( FILE_CONTENT "EOF" )

file(WRITE myFile.txt ${FILE_CONTENT} )

This generates myFile.txt:

#Generated by CMake scripts!
release:foo (single function call)
debug:bar (single function call)
EOF

When I would expect:

#Generated by CMake scripts!
release:foo (two functions call)
debug:bar (two functions call)
release:foo (single function call)
debug:bar (single function call)
EOF

Most likely, the problem is that (set ... PARENT_SCOPE) sets the variable in QMAKE_ADD_RELEASE_AND_DEBUG_LINES_TO_VAR but not in its parent scope...

I tried to replace functions by macros, then I get the right output, but introduces a bug (How to escape accolade characters in CMake) with special characters management. So this is not an acceptable solution for me.

I tried to use cached variable, like this:

function( QMAKE_ADD_LINE_TO_VAR var line )
  set( ${var} "${${var}}\n${line}\n" CACHE INTERNAL "" FORCE )
endfunction()

function( QMAKE_ADD_RELEASE_AND_DEBUG_LINES_TO_VAR var relline debugline )
   QMAKE_ADD_LINE_TO_VAR( ${var} "release:${relline} (two functions call)" )
   QMAKE_ADD_LINE_TO_VAR( ${var} "debug:${debugline} (two functions call)" )
endfunction()

set( FILE_CONTENT "" CACHE INTERNAL "" FORCE )    
QMAKE_ADD_LINE_TO_VAR(FILE_CONTENT "#Generated by CMake scripts!")
QMAKE_ADD_RELEASE_AND_DEBUG_LINES_TO_VAR( FILE_CONTENT "foo" "bar" )
QMAKE_ADD_LINE_TO_VAR( FILE_CONTENT "release:foo (single function call)" )
QMAKE_ADD_LINE_TO_VAR( FILE_CONTENT "debug:bar (single function call)" )
QMAKE_ADD_LINE_TO_VAR( FILE_CONTENT "EOF" )

file(WRITE myFile.txt ${FILE_CONTENT} )

This works, but then, second time I invoke CMake, I get lots of errors due to invalid CMakeCache.txt content.

Any idea to fix that, either with a brand new solution, or with a way to make functions or cached variables work in a better way would be welcomed.

2 Answers 2

1

Add another PARENT_SCOPE assignment in QMAKE_ADD_RELEASE_AND_DEBUG_LINES_TO_VAR, i.e.:

function( QMAKE_ADD_RELEASE_AND_DEBUG_LINES_TO_VAR var relline debugline )
   QMAKE_ADD_LINE_TO_VAR( ${var} "release:${relline} (two functions call)" )
   QMAKE_ADD_LINE_TO_VAR( ${var} "debug:${debugline} (two functions call)" )
   set( ${var} "${${var}}" PARENT_SCOPE )
endfunction()
Sign up to request clarification or add additional context in comments.

Comments

0

The best alternative I found is to actually drop the variable and directly write the file from the function (less efficient, but who really cares...):

function( QMAKE_ADD_LINE_TO_VAR file line )
  file( APPEND ${file} "${line}\n" )
endfunction()

function( QMAKE_ADD_RELEASE_AND_DEBUG_LINES_TO_VAR file relline debugline )
   QMAKE_ADD_LINE_TO_VAR( ${file} "release:${relline} (two functions call)" )
   QMAKE_ADD_LINE_TO_VAR( ${file} "debug:${debugline} (two functions call)" )
endfunction()

file( WRITE myFile.txt "" )
QMAKE_ADD_LINE_TO_VAR(myFile.txt "#Generated by CMake scripts!")
QMAKE_ADD_RELEASE_AND_DEBUG_LINES_TO_VAR( myFile.txt "foo" "bar" )
QMAKE_ADD_LINE_TO_VAR( myFile.txt "release:foo (single function call)" )
QMAKE_ADD_LINE_TO_VAR( myFile.txt "debug:bar (single function call)" )
QMAKE_ADD_LINE_TO_VAR( myFile.txt "EOF" )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.