ccmakeversionexternal-dependencies

extract library version from binary with CMake


I am writing a FindXXX.cmake script for an external C library. I would like my script to provide information about the library version. However, the library only provides this information in the form of a function that returns the version number as a string.

I thought I could extract the version number by having FindXXX.cmake compile the following C program on the fly:

#include <stdio.h>
#include "library.h"

int main() {
  char version[256];
  get_version(version);
  puts(version);
  return 0;
}

In order for this to work, CMake should compile and run the program above at configure time, and use the information it prints as the version identifier. I know how to do the latter (execute_process), and I almost know how to do the former: CheckCSourceRuns comes to mind, but I do not know how to capture the stdout of the generated executable.

TL;DR: is there a way to compile a program, run it and capture its stdout from CMake at generation time?


Solution

  • You may use try_run for that purpose (it is assumed that your source file is named as foo_get_version.c):

    try_run(foo_run_result foo_compile_result
            foo_try_run ${CMAKE_CURRENT_LIST_DIR}/foo_get_version.c
            RUN_OUTPUT_VARIABLE foo_run_output)
    
    if(NOT foo_compile_result)
        # ... Failed to compile
    endif()
    if(NOT foo_run_result EQUAL "0")
        # ... Failed to run
    endif()
    
    # Now 'foo_run_output' variable contains output of your program.
    

    Note, that try_run isn't executed when cross-compiling. Instead, CMake expects that the user will set cache variables foo_run_result and foo_run_result__TRYRUN_OUTPUT.