[CMake] FindPerlLibs.cmake and FindSwig.cmake outdated!
Tristan Carel
tristan.carel at gmail.com
Tue Dec 5 18:58:52 EST 2006
On 12/5/06, Axel Roebel <Axel.Roebel at ircam.fr> wrote:
> Hi,
>
> I just started to add swig support to our project
> http://sourceforge.net/projects/sdif. The project supports
> swig bindings to perl, python and java.
>
> I instantly tried the available
> cmake modules: notably FindSWIG.cmake
> and FindPerlLibs.cmake
>
> I was pretty astonished to find that these
> two macros do not work at all, because most of the
> important information that is necessary
> to find the components is hardcoded
> using fixed version numbers (that are already out of date)
>
> I added patched version of these macros to bug reports 4145
> 4146 in the cmake bug database. These patched versions
> are completely backwards compatible (they use the wrong and fixed path
> locations first before they fall back to the new scheme and use
> the same variables to communicate results)
>
> The idea of the new procedure is to base everything on the FIND_PROGRAM
> macros that searches for the perl/swig binaries
> and (if found) asks the binary via inplace scripts (perl)/command line options
> (swig) all the directory locations that are needed.
>
> This approach is very flexible because by simply setting PERL_EXECUTABLE or
> SWIG_EXECUTABLE on the command line (or the cmake gui)
> one can select an arbitrary perl/swig version
> that is installed on the system.
>
The following concerns `UseSWIG.cmake':
Thanks for what you did, it's a long time this module had to be
rewritten. I guess you're absolutely right to use features provided by
a tool to find its own config directories. I didn't notice that swig
had this option.
Here are some comments (without testing your module):
I guess 2 calls to `FIND_PATH' on the same file `swig.swg' is weird, why don't
you make the EXECUTE_PROCESS before to retrieve the directory given by
`swig -swiglib' and finally make the FIND_PATH of `swig.swg'?
1. Look for swig executable
2. use `swig -swiglib' to get the swiglib path
3. FIND_PATH(SWIG_DIR swig.swg ${SWIG_outlib} /usr/share/swig1.3 ...)
> # - Find SWIG
> # This module finds an installed SWIG. It sets the following variables:
> # SWIG_FOUND - set to true if SWIG is found
> # SWIG_DIR - the directory where swig is installed
> # SWIG_EXECUTABLE - the path to the swig executable
> SET(SWIG_FOUND FOOBAR)
I guess `FALSE' would be cleaner.
> FIND_PATH(SWIG_DIR
> SWIGConfig.cmake
> /usr/share/swig1.3
> /usr/lib/swig1.3
> /usr/local/share/swig1.3)
On Linux, mine are installed in /usr/local/swig/1.3.{29,30,31} without
specifying anything strange during the `./configure'. Maybe you should
add this paths to.
> FIND_PATH(SWIG_DIR
> swig.swg
> /usr/share/swig1.3
> /usr/lib/swig1.3
> /usr/local/share/swig1.3)
> IF(EXISTS ${SWIG_DIR})
> IF("x${SWIG_DIR}x" STREQUAL "x${CMAKE_ROOT}/Modulesx")
> MESSAGE("SWIG_DIR should not be modules subdirectory of CMake")
> ENDIF("x${SWIG_DIR}x" STREQUAL "x${CMAKE_ROOT}/Modulesx")
>
> IF(EXISTS ${SWIG_DIR}/SWIGConfig.cmake)
> INCLUDE(${SWIG_DIR}/SWIGConfig.cmake)
> SET(SWIG_FOUND 1)
> ELSE(EXISTS ${SWIG_DIR}/SWIGConfig.cmake)
> FIND_PROGRAM(SWIG_EXECUTABLE
> NAMES swig-1.3 swig
> PATHS ${SWIG_DIR} ${SWIG_DIR}/.. ${SWIG_DIR}/../../bin /usr/bin /usr/local/bin )
> SET(SWIG_USE_FILE ${CMAKE_ROOT}/Modules/UseSWIG.cmake)
> ENDIF(EXISTS ${SWIG_DIR}/SWIGConfig.cmake)
> ELSE(EXISTS ${SWIG_DIR})
> FIND_PROGRAM(SWIG_EXECUTABLE swig )
> MESSAGE(STATUS "SWIG_EXECUTABLE -- ${SWIG_EXECUTABLE}")
Personnaly I don't like talktative modules. I expect:
IF(SWIG_FIND_QUIETLY)
MESSAGE(STATUS)
ENDIF(SWIG_FIND_QUIETLY)
Whatever you can put the MESSAGE commands at the end of the file to
summary what happened.
> IF(NOT "${SWIG_EXECUTABLE}" STREQUAL "SWIG_EXECUTABLE-NOTFOUND")
IF(NOT SWIG_EXECUTABLE)
is enough, isn't it?
> SET(SWIG ${SWIG_EXECUTABLE})
> EXECUTE_PROCESS(COMMAND ${SWIG} -swiglib OUTPUT_VARIABLE
> SWIG_DIR_TMP)
The command can fail, however it's common to use lower-case for internal
variables:
EXECUTE_PROCESS(COMMAND ${SWIG_EXECUTABLE} -swiglib
OUTPUT_VARIABLE SWIG_swiglib_output
ERROR_VARIABLE SWIG_swiglib_error
RESULT_VARIABLE SWIG_swiglib_result
)
IF(NOT ${SWIG_swiglib_result} EQUAL 0)
MESSAGE(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -swiglib\" failed
with output:\n${SWIG_swiglib_error}")
ENDIF(NOT ${SWIG_swiglib_result} EQUAL 0)
I've got a strange behavior on Windows:
$ which swig
/cygdrive/c/Program Files/swigwin-1.3.31/swig
$ swig -swiglib
c:\Program Files\swigwin-1.3.31\Lib
C:/msys/1.0/local/share/swig/1.3.31
$
... so you have to consider that the command can write several paths.
The best thing would be to only keep the path that "match" the
SWIG_EXECUTABLE path.
I guess a
STRING(REGEX REPLACE "[\n]" ";" SWIG_swiglib_output ${SWIG_swiglib_output})
should be enough to separate the string in several arguments. As there
can be spaces in the paths, you can't use the SEPARATE_ARGUMENT command.
> STRING(REGEX REPLACE "[\n\r]" "" SWIG_DIR_TMP_NOCR ${SWIG_DIR_TMP})
> FIND_PATH(SWIG_DIR swig.swg PATHS "${SWIG_DIR_TMP_NOCR}")
> IF(EXISTS ${SWIG_DIR})
> MESSAGE(STATUS "swig install dir -- ${SWIG_DIR}")
> SET(SWIG_FOUND 1)
> SET(SWIG_USE_FILE ${CMAKE_ROOT}/Modules/UseSWIG.cmake)
> ELSE (EXISTS ${SWIG_DIR})
> MESSAGE(STATUS "swig install dir -- ${SWIG_DIR}")
> ENDIF(EXISTS ${SWIG_DIR})
> ENDIF(NOT "${SWIG_EXECUTABLE}" STREQUAL "SWIG_EXECUTABLE-NOTFOUND")
> ENDIF(EXISTS ${SWIG_DIR})
>
> IF("x${SWIG_FOUND}x" STREQUAL "xFOOBARx")
> SET(SWIG_FOUND 0)
> IF(EXISTS ${SWIG_DIR})
> IF(EXISTS ${SWIG_USE_FILE})
> IF(EXISTS ${SWIG_EXECUTABLE})
> SET(SWIG_FOUND 1)
> ENDIF(EXISTS ${SWIG_EXECUTABLE})
> ENDIF(EXISTS ${SWIG_USE_FILE})
> ENDIF(EXISTS ${SWIG_DIR})
> IF(NOT ${SWIG_FOUND})
> IF(${SWIG_FIND_REQUIRED})
> MESSAGE(FATAL_ERROR "Swig was not found on the system. Please specify the location of Swig.")
> ENDIF(${SWIG_FIND_REQUIRED})
> ENDIF(NOT ${SWIG_FOUND})
> ENDIF("x${SWIG_FOUND}x" STREQUAL "xFOOBARx")
>
IF(NOT SWIG_FOUND)
IF(NOT SWIG_FIND_QUIETLY)
MESSAGE(STATUS "SWIG was not found.")
ELSE(NOT SWIG_FIND_QUIETLY)
IF(SWIG_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "SWIG was not found.")
ENDIF(SWIG_FIND_REQUIRED)
ENDIF(NOT SWIG_FIND_QUIETLY)
ELSE(NOT SWIG_FOUND)
IF(NOT SWIG_FIND_QUIETLY) # put the verbose commands
MESSAGE(STATUS ...)
MESSAGE(STATUS ...)
MESSAGE(STATUS ...)
ENDIF(NOT SWIG_FIND_QUIETLY)
ENDIF(NOT SWIG_FOUND)
I would be glad to discuss with you about how the module could be in
the next release. For example it would be fancy that the module
defines the variable SWIG_VERSION (by using another EXECUTE_PROCESS)
I will test the module tomorrow.
Could you please put a RC2 of the `FindSWIG.cmake' on the bug tracker?
Thanks!
CU
--
Tristan Carel
Music with dinner is an insult both to the cook and the violinist.
More information about the CMake
mailing list