Search code examples
stringintegercmakecomparisonlibxslt

CMake integer comparison not working


I am trying to use CMake to check whether the system has xsltproc installed, and that it comes from libxslt version 1.1.27 or higher. (There's a bug in earlier versions that I don't want to work around.)

When you run xsltproc --version, you get output like this:

Using libxml 20900, libxslt 10128 and libexslt 817
xsltproc was compiled against libxml 20900, libxslt 10128 and libexslt 817
libxslt 10128 was compiled against libxml 20900
libexslt 817 was compiled against livxml 20900

I wrote this CMake code to parse the second integer out of the first line, and am trying to compare it to 10127, which should tell me if I have a new-enough version of xsltproc:

execute_process(COMMAND xsltproc --version
    OUTPUT_VARIABLE XSLTPROC_VERSION ERROR_QUIET)
if(XSLTPROC_VERSION)
    string(REGEX MATCH "libxslt [0-9]+" LIBXSLT_VERSION
        ${XSLTPROC_VERSION})
    if(LIBXSLT_VERSION LESS 10127)  # Always succeeds!  Why?
        message(STATUS "xsltproc found, but it's too old!")
    else()
        message(STATUS "xstlproc found, and new enough")
        set(WORKING_XSLTPROC 1)
    endif()
endif(XSLTPROC_VERSION)

The problem is, no matter what value I get in LIBXSLT_VERSION, the test always succeeds. When I ran it on the system that emitted the first quoted block above, it succeeded as it should, but I then I tried increasing the test value to 10129 to convince myself that it would go down the failure path, but it did not! I later ran it on a system with libxslt 1.1.17, and it also ran down the success path.

I've tried flipping the logic around (i.e. GREATER 10126), using VERSION_LESS and STRLESS, etc. I've also tried switching the bare integer to a string, dereferencing the variable name so it's a straight string-to-string comparison, etc. Nothing helps.

I'm mostly working with CMake 2.6 and 2.8.


Solution

  • It just looks like a problem with the regex handling.

    When you call:

    string(REGEX MATCH "libxslt [0-9]+" LIBXSLT_VERSION ${XSLTPROC_VERSION})
    

    the value of LIBXSLT_VERSION will be libxslt 10128, not the bare version 10128.


    You can capture just the version number by modifying your regex to "libxslt ([0-9]+)" and reference the captured match in the variable CMAKE_MATCH_1 (CMAKE_MATCH_0 contains the full match; equivalent to ${LIBXSLT_VERSION} here, i.e. libxslt 10128).

    So, you should be able to do something like:

    if(XSLTPROC_VERSION)
        string(REGEX MATCH "libxslt ([0-9]+)" LIBXSLT_VERSION ${XSLTPROC_VERSION})
        if(NOT CMAKE_MATCH_1)
            message(AUTHOR_WARNING "Error during check for xslt version.")
        elseif(CMAKE_MATCH_1 LESS 10127)
            message(STATUS "xsltproc found, but it's too old!")
        else()
            message(STATUS "xstlproc found, and new enough")
            set(WORKING_XSLTPROC 1)
        endif()
    endif()