[CMake] Return values from CMake functions?

2008-11-20 Thread Bartlett, Roscoe A
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?

2008-11-20 Thread Ken Martin
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 I’m 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?

2008-11-20 Thread Bartlett, Roscoe A
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?

2008-11-20 Thread Ken Martin
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