[Cmake] FILE WRITE and TRY_COMPILE

William A. Hoffman billlist at nycap.rr.com
Thu, 06 May 2004 16:40:05 -0400


I just tried your example and there are some problems with it.
Can you simplify it a bit and see if you can get it to fail?

I tried this:

PROJECT(bar)
INCLUDE(${bar_SOURCE_DIR}/CheckPrototypeExistsCXX.cmake)
CHECK_PROTOTYPE_EXISTS_CXX(foo iostream bar)

It seems to have some backwards logic, in that it says foo exists but has
an error in the output log that should only have passed stuff.  But,
I don't get any complaints about the loop problem.   

In the directory with the problem, can you look at the Makefile and
right at the top it has a commented list of sources used to generate the
file.  See if c:/software/tmp/CheckPrototypeExists.cxx is one of them.


-Bill

At 03:47 PM 5/6/2004, Amitha Perera wrote:
>On Thu 06 May 2004, Andy Cedilnik wrote:
>> Could you write example for where it fails?
>
>See below.
>
>On Thu 06 May 2004, William A. Hoffman wrote:
>> To clarify further, the problem that FILE_WRITE is talking about
>> only happens when you do something like this:
>> 
>> FILE_WRITE(foo.cmake)
>> INCLUDE(foo.cmake)
>
>That's what I thought. However, the error made me think I'd misunderstood.
>
>> TRY_COMPILE creates a completely separate cmake environment.   I suppose
>> if you put the FILE_WRITE into a CMakeList file in a trycompile directory
>> you would get the error and would have a problem.  Is that the case
>> in VXL?
>
>I don't think so. The revelant macro is below. As far as I can tell,
>the cause is what is now the CONFIGURE_FILE line, just before the
>TRY_COMPILE. (The contents of the cxx.in file is below the macro
>code.) Previously, the CONFIGURE_FILE line used to be a FILE WRITE:
>
>
>        FILE(WRITE ${CHECK_PROTOTYPE_EXISTS_FILE}
>          "#include <${FILE}>\n"
>          ${CHECK_PROTOTYPE_EXISTS_EXTERNC_BEGIN}
>          "typedef union { int member; } dummyStruct;\n"
>          "dummyStruct ${FUNC}( dummyStruct );\n"
>          ${CHECK_PROTOTYPE_EXISTS_EXTERNC_END}
>          "int main(){return 0;}\n" )
>
>
>This caused an error: 
>
>   CMake Error: File c:/software/tmp/CheckPrototypeExists.cxx is
>   written by WRITE_FILE (or FILE WRITE) command and should not be used
>   as input to CMake. Please use CONFIGURE_FILE to be safe. Refer to the
>   note next to FILE WRITE command.
>
>
>Amitha.
>
>
>-------- CheckPrototypeExistsCXX.cmake ------------------------------------
>
>#
># This checks if a prototype for FUNC (with C linkage) has been
># declared in any one of the header files listed in INCLUDE. It uses
># the C++ compiler.
>#
># (The check is actually whether declaring a prototype will cause a
># conflict and thus an error. The results may differ depending on the
># compiler. For example, gcc under Cygwin will issue a warning but g++
># will issue an error. In the DCMTK, the prototypes are used in a C++
># context, so we use the C++ compiler to check.
>#
>MACRO(CHECK_PROTOTYPE_EXISTS_CXX FUNC INCLUDE VARIABLE)
>  IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
>    SET( CHECK_PROTOTYPE_EXISTS_CXX_FILE_IN "${VXL_CMAKE_DIR}/CheckPrototypeExists.cxx.in" )
>    SET( CHECK_PROTOTYPE_EXISTS_CXX_FILE "${CMAKE_BINARY_DIR}/CMakeTmp/CheckPrototypeExists.cxx" )
>    SET( CHECK_PROTOTYPE_EXISTS_CXX_EXTERNC_BEGIN "extern \"C\" {\n" )
>    SET( CHECK_PROTOTYPE_EXISTS_CXX_EXTERNC_END "}\n" )
>
>    SET(MACRO_CHECK_PROTOTYPE_EXISTS_CXX_FLAGS ${CMAKE_REQUIRED_FLAGS})
>    MESSAGE(STATUS "Looking for prototype for ${FUNC} in ${INCLUDE}")
>
>    SET( ${VARIABLE} 0 )
>    FOREACH(FILE ${INCLUDE})
>
>      # First check if the header exists. Cache the result in a variable named after
>      # the header, so that we don't re-do the effort
>      STRING( REGEX REPLACE "\\.|/" "_" CLEAN_FILE ${FILE} )
>      SET( CHECK_PROTOTYPE_EXISTS_CXX_INCLUDE "CHECK_PROTOTYPE_EXISTS_CXX_INCLUDE_${CLEAN_FILE}" )
>      CHECK_INCLUDE_FILE( ${FILE} ${CHECK_PROTOTYPE_EXISTS_CXX_INCLUDE} )
>      IF( CHECK_PROTOTYPE_EXISTS_CXX_INCLUDE )
>
>        FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeOutput.log "Trying struct with ${FILE}\n" )
>        CONFIGURE_FILE( ${CHECK_PROTOTYPE_EXISTS_CXX_FILE_IN}
>                        ${CHECK_PROTOTYPE_EXISTS_CXX_FILE} IMMEDIATE )
>
>        TRY_COMPILE( CHECK_PROTOTYPE_EXISTS_CXX_RESULT
>          ${CMAKE_BINARY_DIR}
>          ${CHECK_PROTOTYPE_EXISTS_CXX_FILE}
>          CMAKE_FLAGS 
>          -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_PROTOTYPE_EXISTS_CXX_FLAGS}
>          OUTPUT_VARIABLE OUTPUT)
>        IF( CHECK_PROTOTYPE_EXISTS_CXX_RESULT ) 
>          FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeOutput.log 
>            "Determining if prototype ${FUNC} exists in ${FILE} "
>            "failed with the following output:\n"
>            "${OUTPUT}\n\n")
>        ELSE( CHECK_PROTOTYPE_EXISTS_CXX_RESULT ) 
>          FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeOutput.log 
>            "Determining if prototype ${FUNC} exists in ${FILE} "
>            "passed with the following output:\n"
>            "${OUTPUT}\n\n")
>          MESSAGE(STATUS "    Found in ${FILE}")
>          SET( ${VARIABLE} 1 )
>        ENDIF( CHECK_PROTOTYPE_EXISTS_CXX_RESULT )
>
>      ENDIF( CHECK_PROTOTYPE_EXISTS_CXX_INCLUDE )
>    ENDFOREACH(FILE)
>
>    IF( ${VARIABLE} )
>      MESSAGE(STATUS "Looking for prototype of ${FUNC} - found")
>      SET(${VARIABLE} 1 CACHE INTERNAL "Have prototype ${VARIABLE}")
>    ELSE(${VARIABLE})
>      MESSAGE(STATUS "Looking for prototype of ${FUNC} - not found")
>      SET(${VARIABLE} "" CACHE INTERNAL "Have prototype ${VARIABLE}")
>    ENDIF(${VARIABLE})
>  ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
>ENDMACRO(CHECK_PROTOTYPE_EXISTS_CXX)
>
>
>
>
>------- CheckPrototypeExists.cxx.in ---------------------------------------
>
>
>${CHECK_PROTOTYPE_EXISTS_CXX_EXTERNC_BEGIN}
>
>typedef union { int member; } dummyStruct;
>
>dummyStruct ${FUNC}( dummyStruct );
>
>${CHECK_PROTOTYPE_EXISTS_CXX_EXTERNC_END}
>
>int main() {
>  return 0;
>}
>
>---------------------------------------------------------------------------
>_______________________________________________
>Cmake mailing list
>Cmake at www.cmake.org
>http://www.cmake.org/mailman/listinfo/cmake