[CMake] Return values from CMake functions?
Hello, Has anyone thought about the possibility of adding return values from CMake functions? This would be a very useful language feature that the Trilinos CMake files would use everywhere. Here is an example use case. One problem with CMake is that it has very loose checking. For example, if I write: IF (MYVARABLE) ... ENDIF() Instead of what I meant: IF (MYVARIABLE) ... ENDIF() then my CMakeLists.txt file will not work correctly. What I have been doing is to instead write an ASSERT_DEFINED(...) macro and then use it as: ASSERT_DEFINED(MYVARIABLE) IF (MYVARIABLE) ... ENDIF() Of course the problem with this is that I could misspell one of the uses as: ASSERT_DEFINED(MYVARIABLE) IF (MYVARABLE) ... ENDIF() and I am back in the same situation. The problem is that I am duplicating the variable name. This is a fundamental software engineering issue that needs to be addressed in some way. What I would like to be able to write is a function like: FUNCTION(ASSERTDEF VARNAME) IF(NOT DEFINED ${VARNAME}) MESSAGE(SEND_ERROR "Error, the variable ${VARNAME} is not defined!") ENDIF() RETURN(${VARNAME}) ENDFUNCTION() You could then use this function like: IF (${ASSERTDEF(MYVARIABLE)$) ... ENDIF() Then, if I misspelled the variable name as: IF (${ASSERTDEF(MYVARABLE)}$) ... ENDIF() I would get an error message and processing would stop immediately. Above, I assume that the syntax: ${SOMEFUNCTION(ARGS)} Is needed to get CMake to expect a return value from the function and then return it, just like it would return a variables value. How hard would it be to all return values from CMake functions in this way? Thanks, - Ross ___ CMake mailing list CMake@cmake.org http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Return values from CMake functions?
While not super sexy, you can do what you are looking for with a minor twist. The following code illustrates it. function(assertdef VARNAME RESULT_NAME) if(NOT DEFINED ${VARNAME}) message(SEND_ERROR "Error, the variable ${VARNAME} is not defined!") endif() set (${RESULT_NAME} ${VARNAME} PARENT_SCOPE) endfunction() # comment the next line to see the two different results set (myvar 1) assertdef(myvar varname) if (${varname}) message("${varname} is true") endif() With respect to the general question of functions returning values it could be done but it is a bit of a big change. Functions and commands look the same (and should act the same IMO) to the people using them. So really we are talking about commands returning values. This is mostly just a syntax issue. Right now we have command(arg arg arg ) to support return values we need something that could handle command (arg command2(arg arg) arg arg ) or in your case if(assertdef(foo)) or in another case set(foo get_property( )) etc. This hits the parser and the argument processing in CMake but I think it could be done. I guess Im not sure if we *should* do it. Open to opinions here. Ken Ken Martin PhD Kitware Inc. 28 Corporate Drive Clifton Park NY 12065 [EMAIL PROTECTED] 518 371 3971 (w/f) From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Bartlett, Roscoe A Sent: Thursday, November 20, 2008 11:19 AM To: cmake@cmake.org Subject: [CMake] Return values from CMake functions? Hello, Has anyone thought about the possibility of adding return values from CMake functions? This would be a very useful language feature that the Trilinos CMake files would use everywhere. Here is an example use case. One problem with CMake is that it has very loose checking. For example, if I write: IF (MYVARABLE) ... ENDIF() Instead of what I meant: IF (MYVARIABLE) ... ENDIF() then my CMakeLists.txt file will not work correctly. What I have been doing is to instead write an ASSERT_DEFINED(...) macro and then use it as: ASSERT_DEFINED(MYVARIABLE) IF (MYVARIABLE) ... ENDIF() Of course the problem with this is that I could misspell one of the uses as: ASSERT_DEFINED(MYVARIABLE) IF (MYVARABLE) ... ENDIF() and I am back in the same situation. The problem is that I am duplicating the variable name. This is a fundamental software engineering issue that needs to be addressed in some way. What I would like to be able to write is a function like: FUNCTION(ASSERTDEF VARNAME) IF(NOT DEFINED ${VARNAME}) MESSAGE(SEND_ERROR "Error, the variable ${VARNAME} is not defined!") ENDIF() RETURN(${VARNAME}) ENDFUNCTION() You could then use this function like: IF (${ASSERTDEF(MYVARIABLE)$) ... ENDIF() Then, if I misspelled the variable name as: IF (${ASSERTDEF(MYVARABLE)}$) ... ENDIF() I would get an error message and processing would stop immediately. Above, I assume that the syntax: ${SOMEFUNCTION(ARGS)} Is needed to get CMake to expect a return value from the function and then return it, just like it would return a variables value. How hard would it be to all return values from CMake functions in this way? Thanks, - Ross ___ CMake mailing list CMake@cmake.org http://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Return values from CMake functions?
Ken, > -Original Message- > From: Ken Martin [mailto:[EMAIL PROTECTED] > Sent: Thursday, November 20, 2008 11:08 AM > To: Bartlett, Roscoe A; cmake@cmake.org > Subject: RE: [CMake] Return values from CMake functions? > > While not super sexy, you can do what you are looking for > with a minor twist. The following code illustrates it. > > function(assertdef VARNAME RESULT_NAME) > if(NOT DEFINED ${VARNAME}) > message(SEND_ERROR "Error, the variable ${VARNAME} is > not defined!") > endif() > set (${RESULT_NAME} ${VARNAME} PARENT_SCOPE) > endfunction() > > # comment the next line to see the two different results set (myvar 1) > > assertdef(myvar varname) > if (${varname}) > message("${varname} is true") > endif() The above example you show does not solve the problem. You are still typing 'varname' twice and therefore, you could still type: assertdef(myvar varname) if (${varnames}) message("${varname} is true") endif() and your code is wrong. If CMake could add a mode where all variables had to be defined before being used (like with 'use strict' in Perl), then this particular use case would go away. However, the general issue of function returns still remains and would make a good bit of CMake code a lot smaller and cleaner. > With respect to the general question of functions returning > values it could be done but it is a bit of a big change. > Functions and commands look the same (and should act the same > IMO) to the people using them. So really we are talking about > commands returning values. This is mostly just a syntax > issue. Right now we have > > command(arg arg arg...) > > to support return values we need something that could handle ... > > command (arg command2(arg arg) arg arg ...) > > or in your case > > if(assertdef(foo)) > > or in another case > > set(foo get_property(...)) > > etc. This hits the parser and the argument processing in > CMake but I think it could be done. I guess I'm not sure if > we *should* do it. Open to opinions here. The suggestion I had was to use the ${SOMETHING(...)} syntax to invoke a function call. So you would have: command (arg ${command2(arg arg)} arg arg ...) instead of command (arg command2(arg arg) arg arg ...) The CMake parser already has to handle ${SOMETHING} or order to extract variable values. What I am suggesting is that you just update the logic in the handler for variable dereferencing to consider function/command invocations ${SOMEFUNCTION(...)}. In this way, you would *not* effect the parser, just the handler for variable dereferencing. Does that this seem reasonable? Arguing that CMake does not need function returns is like arguing that C, C++, Perl, Python, Java, Fortran (77, 90, 95, 2003, 2008) etc. do not really need function returns. It is a very useful programming language feature and that is way every serious language supports it. Cheers, - Ross > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf Of Bartlett, Roscoe A > Sent: Thursday, November 20, 2008 11:19 AM > To: cmake@cmake.org > Subject: [CMake] Return values from CMake functions? > > Hello, > > Has anyone thought about the possibility of adding return > values from CMake functions? This would be a very useful > language feature that the Trilinos CMake files would use everywhere. > > Here is an example use case. One problem with CMake is that > it has very loose checking. For example, if I write: > >IF (MYVARABLE) > ... >ENDIF() > > Instead of what I meant: > >IF (MYVARIABLE) > ... >ENDIF() > > then my CMakeLists.txt file will not work correctly. What I > have been doing is to instead write an ASSERT_DEFINED(...) > macro and then use it as: > >ASSERT_DEFINED(MYVARIABLE) >IF (MYVARIABLE) > ... >ENDIF() > > Of course the problem with this is that I could misspell one > of the uses as: > >ASSERT_DEFINED(MYVARIABLE) >IF (MYVARABLE) > ... >ENDIF() > > and I am back in the same situation. The problem is that I > am duplicating the variable name. This is a fundamental > software engineering issue that needs to be addressed in some way. > > What I would like to be able to write is a function like: > > FUNCTION(ASSERTDEF VARNAME) > IF(NOT DEFINED ${VARNAME}) > MESSAGE(SEND_ERROR "Error, the variable ${VARNAME} is > not defined!") > ENDIF() > RETURN(${VARNAME}) > ENDFUNCTION() > > You could then use this function like: > >IF (${ASSERTDEF(MYVARIABLE)$) > ... >ENDIF() > > Then, if I misspelled the variable name as:
Re: [CMake] Return values from CMake functions?
True, if you mismatch the typing of varname it fails. At least with this approach it can be a fairly short variable and not something like CXX_SHARED_LIBRARY_LINKER_FLAGS_DEBUG which begs to have typos in it :-) > The suggestion I had was to use the ${SOMETHING(...)} syntax to invoke a function call. So you would have: I don't think you need the ${} syntax. Such syntax could be used, but just SOMETHING(...) would work as well. I remembered that the CVS version of CMake has some parser changes already in it that allow for if (func()) to be parsed. It is mainly a matter of the argument expansion code being modified to actually call func when it sees it followed by a pair of parens. That and a bunch of changes to the signature of commands to allow for return values/debugging info/etc. That is the bigger task. I'm assuming it would be zero or more return values like lua, no reason to limit it to just zero or one like C. Ken Ken Martin PhD Kitware Inc. 28 Corporate Drive Clifton Park NY 12065 [EMAIL PROTECTED] 518 371 3971 (w/f) ___ CMake mailing list CMake@cmake.org http://www.cmake.org/mailman/listinfo/cmake