Blame cmake/AutoconfHelper.cmake

Packit cdaae3
# Helper functions for translating autoconf projects. Several functions
Packit cdaae3
# are lifted from the Mono sources
Packit cdaae3
Packit cdaae3
include (CheckCSourceCompiles)
Packit cdaae3
include (CheckIncludeFile)
Packit cdaae3
include (TestBigEndian)
Packit cdaae3
include (CheckFunctionExists)
Packit cdaae3
include (CheckTypeSize)
Packit cdaae3
include (CheckCSourceRuns)
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Function to get the version information from the configure.ac file in the
Packit cdaae3
# current directory. Its argument is the name of the library as passed to
Packit cdaae3
# AC_INIT. It will set the variables ${LIBNAME}_VERSION and ${LIBNAME}_SOVERSION
Packit cdaae3
function (ac_get_version libname)
Packit cdaae3
  string(TOUPPER "${libname}" libname_upper)
Packit cdaae3
  
Packit cdaae3
  # Read the relevant content from configure.ac
Packit cdaae3
  file (STRINGS configure.ac tmp_configure_ac
Packit cdaae3
    REGEX "${libname_upper}_[_A-Z]+=[ \\t]*[0-9]+")
Packit cdaae3
  
Packit cdaae3
  # Product version
Packit cdaae3
  string (REGEX REPLACE ".+MAJOR[_A-Z]+=([0-9]+).+MINOR[_A-Z]+=([0-9]+).+MICRO[_A-Z]+=([0-9]+).*"
Packit cdaae3
    "\\1.\\2.\\3" ${libname_upper}_VERSION "${tmp_configure_ac}")
Packit cdaae3
    
Packit cdaae3
  # Library version for libtool
Packit cdaae3
  string (REGEX REPLACE ".+CURRENT=([0-9]+).+REVISION=([0-9]+).+AGE=([0-9]+).*"
Packit cdaae3
    "\\1.\\2.\\3" ${libname_upper}_SOVERSION "${tmp_configure_ac}")
Packit cdaae3
  
Packit cdaae3
  # Checks if the string needs to be displayed
Packit cdaae3
  set (${libname_upper}_DISPLAYSTR_AUX 
Packit cdaae3
    "Found ${libname} version ${${libname_upper}_VERSION}, soversion ${${libname_upper}_SOVERSION} from configure.ac"
Packit cdaae3
  )
Packit cdaae3
  if ((NOT ${libname_upper}_DISPLAYSTR) OR (NOT ${libname_upper}_DISPLAYSTR STREQUAL ${libname_upper}_DISPLAYSTR_AUX))
Packit cdaae3
    set (${libname_upper}_DISPLAYSTR ${${libname_upper}_DISPLAYSTR_AUX} 
Packit cdaae3
      CACHE INTERNAL "Version string from ${libname}" FORCE)
Packit cdaae3
    message (STATUS ${${libname_upper}_DISPLAYSTR})
Packit cdaae3
  endif ()
Packit cdaae3
  
Packit cdaae3
  # Export the result to the caller
Packit cdaae3
  set(${libname_upper}_VERSION "${${libname_upper}_VERSION}" PARENT_SCOPE)
Packit cdaae3
  set(${libname_upper}_SOVERSION "${${libname_upper}_SOVERSION}" PARENT_SCOPE)
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Also from mono's source code
Packit cdaae3
# Implementation of AC_CHECK_HEADERS
Packit cdaae3
# In addition, it also records the list of variables in the variable 
Packit cdaae3
# 'autoheader_vars', and for each variable, a documentation string in the
Packit cdaae3
# variable ${var}_doc
Packit cdaae3
function(ac_check_headers)
Packit cdaae3
  foreach (header ${ARGV})
Packit cdaae3
	string(TOUPPER ${header} header_var)
Packit cdaae3
	string(REPLACE "." "_" header_var ${header_var})
Packit cdaae3
	string(REPLACE "/" "_" header_var ${header_var})
Packit cdaae3
	set(header_var "HAVE_${header_var}")
Packit cdaae3
	check_include_file (${header} ${header_var})
Packit cdaae3
	set("${header_var}_doc" "Define to 1 if you have the <${header}> header file." PARENT_SCOPE)
Packit cdaae3
	if (${header_var})
Packit cdaae3
	  set("${header_var}_defined" "1" PARENT_SCOPE)
Packit cdaae3
	endif()
Packit cdaae3
	set("${header_var}_val" "1" PARENT_SCOPE)
Packit cdaae3
	set (autoheader_vars ${autoheader_vars} ${header_var})
Packit cdaae3
  endforeach()
Packit cdaae3
  set (autoheader_vars ${autoheader_vars} PARENT_SCOPE)
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
# Function taken from mono's source code
Packit cdaae3
function (ac_check_funcs)
Packit cdaae3
  foreach (func ${ARGV})
Packit cdaae3
    string(TOUPPER ${func} var)
Packit cdaae3
    set(var "HAVE_${var}")
Packit cdaae3
    set(${var})
Packit cdaae3
    check_function_exists (${func} ${var})
Packit cdaae3
    set("${var}_doc" "Define to 1 if you have the '${func}' function." PARENT_SCOPE)
Packit cdaae3
    if (${var})
Packit cdaae3
      set("${var}_defined" "1" PARENT_SCOPE)
Packit cdaae3
      set(${var} yes PARENT_SCOPE)
Packit cdaae3
    endif()
Packit cdaae3
    set("${var}_val" "1" PARENT_SCOPE)
Packit cdaae3
    set (autoheader_vars ${autoheader_vars} ${var})
Packit cdaae3
  endforeach()
Packit cdaae3
  set (autoheader_vars ${autoheader_vars} PARENT_SCOPE)
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Specifically, this macro checks for stdlib.h', stdarg.h',
Packit cdaae3
# string.h', and float.h'; if the system has those, it probably
Packit cdaae3
# has the rest of the ANSI C header files.  This macro also checks
Packit cdaae3
# whether string.h' declares memchr' (and thus presumably the
Packit cdaae3
# other mem' functions), whether stdlib.h' declare free' (and
Packit cdaae3
# thus presumably malloc' and other related functions), and whether
Packit cdaae3
# the ctype.h' macros work on characters with the high bit set, as
Packit cdaae3
# ANSI C requires.
Packit cdaae3
function (ac_header_stdc)
Packit cdaae3
  if (STDC_HEADERS)
Packit cdaae3
    return()
Packit cdaae3
  endif()
Packit cdaae3
  message(STATUS "Looking for ANSI-C headers")
Packit cdaae3
  set(code "
Packit cdaae3
#include <stdlib.h>
Packit cdaae3
#include <stdarg.h>
Packit cdaae3
#include <string.h>
Packit cdaae3
#include <float.h>
Packit cdaae3
Packit cdaae3
int main(int argc, char **argv)
Packit cdaae3
{
Packit cdaae3
  void *ptr;
Packit cdaae3
  free((void*)1);
Packit cdaae3
  ptr = memchr((void*)1, 0, 0);
Packit cdaae3
Packit cdaae3
  return (int)ptr;
Packit cdaae3
}
Packit cdaae3
")
Packit cdaae3
  # FIXME Check the ctype.h high bit
Packit cdaae3
  CHECK_C_SOURCE_COMPILES("${code}" STDC_HEADERS)
Packit cdaae3
  if (STDC_HEADERS)
Packit cdaae3
    set(STDC_HEADERS 1 PARENT_SCOPE)
Packit cdaae3
	message(STATUS "Looking for ANSI-C headers - found")
Packit cdaae3
  else()
Packit cdaae3
    message(STATUS "Looking for ANSI-C headers - not found")
Packit cdaae3
  endif()
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Also from the mono sources, kind of implements AC_SYS_LARGEFILE
Packit cdaae3
function (ac_sys_largefile)
Packit cdaae3
  CHECK_C_SOURCE_RUNS("
Packit cdaae3
#include <sys/types.h>
Packit cdaae3
#define BIG_OFF_T (((off_t)1<<62)-1+((off_t)1<<62))
Packit cdaae3
int main (int argc, char **argv) {
Packit cdaae3
    int big_off_t=((BIG_OFF_T%2147483629==721) &&
Packit cdaae3
                   (BIG_OFF_T%2147483647==1));
Packit cdaae3
    return big_off ? 0 : 1;
Packit cdaae3
}
Packit cdaae3
" HAVE_LARGE_FILE_SUPPORT)
Packit cdaae3
Packit cdaae3
# Check if it makes sense to define _LARGE_FILES or _FILE_OFFSET_BITS
Packit cdaae3
  if (HAVE_LARGE_FILE_SUPPORT)
Packit cdaae3
    return()
Packit cdaae3
  endif()
Packit cdaae3
  
Packit cdaae3
  set (_LARGE_FILE_EXTRA_SRC "
Packit cdaae3
#include <sys/types.h>
Packit cdaae3
int main (int argc, char **argv) {
Packit cdaae3
  return sizeof(off_t) == 8 ? 0 : 1;
Packit cdaae3
}
Packit cdaae3
")
Packit cdaae3
  CHECK_C_SOURCE_RUNS ("#define _LARGE_FILES\n${_LARGE_FILE_EXTRA_SRC}" 
Packit cdaae3
    HAVE_USEFUL_D_LARGE_FILES)
Packit cdaae3
  if (NOT HAVE_USEFUL_D_LARGE_FILES)
Packit cdaae3
    if (NOT DEFINED HAVE_USEFUL_D_FILE_OFFSET_BITS)
Packit cdaae3
      set (SHOW_LARGE_FILE_WARNING TRUE)
Packit cdaae3
    endif ()
Packit cdaae3
    CHECK_C_SOURCE_RUNS ("#define _FILE_OFFSET_BITS 64\n${_LARGE_FILE_EXTRA_SRC}"
Packit cdaae3
      HAVE_USEFUL_D_FILE_OFFSET_BITS)
Packit cdaae3
	  if (HAVE_USEFUL_D_FILE_OFFSET_BITS)
Packit cdaae3
      set (_FILE_OFFSET_BITS 64 PARENT_SCOPE)
Packit cdaae3
	  elseif (SHOW_LARGE_FILE_WARNING)
Packit cdaae3
	    message (WARNING "No 64 bit file support through off_t available.")
Packit cdaae3
	  endif ()
Packit cdaae3
  else ()
Packit cdaae3
    set (_LARGE_FILES 1 PARENT_SCOPE)
Packit cdaae3
  endif ()
Packit cdaae3
endfunction ()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Quick way to set some basic variables
Packit cdaae3
# FIXME add support for variable number of arguments: only package and version are mandatory
Packit cdaae3
# arguments are package version bug_report tarname url
Packit cdaae3
function (ac_init)
Packit cdaae3
    set(package ${ARGV0})
Packit cdaae3
    set(version ${ARGV1})
Packit cdaae3
    set(bug_report ${ARGV2})
Packit cdaae3
    set(tarname ${ARGV3})
Packit cdaae3
    set(url ${ARGV4})
Packit cdaae3
    set(PACKAGE_NAME "\"${package}\"" PARENT_SCOPE)
Packit cdaae3
    set(PACKAGE_VERSION "\"${version}\"" PARENT_SCOPE)
Packit cdaae3
    set(VERSION "\"${version}\"" PARENT_SCOPE)
Packit cdaae3
    if(version)
Packit cdaae3
        set(PACKAGE_STRING "\"${package} ${version}\"" PARENT_SCOPE)
Packit cdaae3
    else()
Packit cdaae3
        set(PACKAGE_STRING "\"${package}\"" PARENT_SCOPE)
Packit cdaae3
    endif()
Packit cdaae3
    
Packit cdaae3
    set(PACKAGE_BUGREPORT "\"${bug_report}\"" PARENT_SCOPE)
Packit cdaae3
    
Packit cdaae3
    if(NOT tarname)
Packit cdaae3
        string(REGEX REPLACE "[^a-zA-Z0-9_]" "-" tarname "${package}")
Packit cdaae3
    endif()    
Packit cdaae3
    set(PACKAGE_TARNAME "\"${tarname}\"" PARENT_SCOPE)
Packit cdaae3
    
Packit cdaae3
    set(PACKAGE_URL "\"${url}\"" PARENT_SCOPE)
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Checks for the const keyword, defining "HAS_CONST_SUPPORT"
Packit cdaae3
# If it does not have support, defines "const" to 0 in the parent scope
Packit cdaae3
function (ac_c_const)
Packit cdaae3
  CHECK_C_SOURCE_COMPILES(
Packit cdaae3
    "int main(int argc, char **argv){const int r = 0;return r;}"
Packit cdaae3
    HAS_CONST_SUPPORT)
Packit cdaae3
  if (NOT HAS_CONST_SUPPORT)
Packit cdaae3
    set(const 0 PARENT_SCOPE)
Packit cdaae3
  endif()
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Inline keyword support. Defines "inline" in the parent scope to the
Packit cdaae3
# compiler internal keyword for inline in C
Packit cdaae3
# TODO write a better test!
Packit cdaae3
function (ac_c_inline)
Packit cdaae3
  if (MSVC)
Packit cdaae3
    set (inline __inline)
Packit cdaae3
  elseif(CMAKE_COMPILER_IS_GNUC)
Packit cdaae3
    set (inline __inline__)
Packit cdaae3
  endif()
Packit cdaae3
  set(inline "${inline}" PARENT_SCOPE)
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Test if you can safely include both <sys/time.h> and <time.h>
Packit cdaae3
function (ac_header_time)
Packit cdaae3
  CHECK_C_SOURCE_COMPILES(
Packit cdaae3
    "#include <sys/time.h>\n#include <time.h>\nint main(int argc, char **argv) { return 0; }" 
Packit cdaae3
    TIME_WITH_SYS_TIME)
Packit cdaae3
  set(TIME_WITH_SYS_TIME ${TIME_WITH_SYS_TIME} PARENT_SCOPE)
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
Packit cdaae3
# (Intel), setting "WORDS_BIGENDIAN" to 1 if big endian
Packit cdaae3
function (ac_c_bigendian)
Packit cdaae3
  TEST_BIG_ENDIAN(HOST_BIGENDIAN)
Packit cdaae3
  if (HOST_BIGENDIAN)
Packit cdaae3
    set(WORDS_BIGENDIAN 1 PARENT_SCOPE)
Packit cdaae3
  endif()
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Check for off_t, setting "off_t" in the parent scope
Packit cdaae3
function(ac_type_off_t)
Packit cdaae3
  CHECK_TYPE_SIZE("off_t" SIZEOF_OFF_T)
Packit cdaae3
  if (NOT SIZEOF_OFF_T)
Packit cdaae3
    set(off_t "long int")
Packit cdaae3
  endif()
Packit cdaae3
  set(off_t ${off_t} PARENT_SCOPE)
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Check for size_t, setting "size_t" in the parent scope
Packit cdaae3
function(ac_type_size_t)
Packit cdaae3
  CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T)
Packit cdaae3
  if (NOT SIZEOF_SIZE_T)
Packit cdaae3
    set(size_t "unsigned int")
Packit cdaae3
  endif()
Packit cdaae3
  set(size_t ${size_t} PARENT_SCOPE)
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Define "TM_IN_SYS_TIME" to 1 if <sys/time.h> declares "struct tm"
Packit cdaae3
function(ac_struct_tm)
Packit cdaae3
  CHECK_C_SOURCE_COMPILES(
Packit cdaae3
    "#include <sys/time.h>\nint main(int argc, char **argv) { struct tm x; return 0; }"
Packit cdaae3
    TM_IN_SYS_TIME
Packit cdaae3
  )
Packit cdaae3
  if (TM_IN_SYS_TIME)
Packit cdaae3
    set (TM_IN_SYS_TIME 1 PARENT_SCOPE)
Packit cdaae3
  endif()
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Obtain size of an 'type' and define as SIZEOF_TYPE
Packit cdaae3
function (ac_check_sizeof typename)
Packit cdaae3
  string(TOUPPER "SIZEOF_${typename}" varname)
Packit cdaae3
	string(REPLACE " " "_" varname "${varname}")
Packit cdaae3
  string(REPLACE "*" "p" varname "${varname}")
Packit cdaae3
  CHECK_TYPE_SIZE("${typename}" ${varname} BUILTIN_TYPES_ONLY)
Packit cdaae3
  if(NOT ${varname})
Packit cdaae3
    set(${varname} 0 PARENT_SCOPE)
Packit cdaae3
  endif()
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Check if the type exists, defines HAVE_<type>
Packit cdaae3
function (ac_check_type typename)
Packit cdaae3
  string(TOUPPER "${typename}" varname)
Packit cdaae3
	string(REPLACE " " "_" varname "${varname}")
Packit cdaae3
  string(REPLACE "*" "p" varname "${varname}")
Packit cdaae3
  CHECK_TYPE_SIZE("${typename}" ${varname})
Packit cdaae3
  if (NOT "${varname}" STREQUAL "")
Packit cdaae3
    set("HAVE_${varname}" 1 PARENT_SCOPE)
Packit cdaae3
    set("${varname}" "${typename}" PARENT_SCOPE)
Packit cdaae3
  else()
Packit cdaae3
    set("${varname}" "unknown" PARENT_SCOPE)  
Packit cdaae3
  endif()
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
Packit cdaae3
# Verifies if each type on the list exists, using the given prelude
Packit cdaae3
function (ac_check_types type_list prelude)
Packit cdaae3
  foreach(typename ${type_list})
Packit cdaae3
    string(TOUPPER "HAVE_${typename}" varname)
Packit cdaae3
    string(REPLACE " " "_" varname "${varname}")
Packit cdaae3
    string(REPLACE "*" "p" varname "${varname}")
Packit cdaae3
    CHECK_C_SOURCE_COMPILES("${prelude}\n ${typename} foo;" ${varname})
Packit cdaae3
  endforeach()
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
function(ac_path_prog variable prog_to_check_for value_if_not_found env_var)
Packit cdaae3
    find_program(${variable} NAMES ${prog_to_check_for} PATHS ENV ${env_var} NO_DEFAULT_PATH)
Packit cdaae3
    if(NOT ${variable})
Packit cdaae3
        message(STATUS "Looking for ${prog_to_check_for} - not found")
Packit cdaae3
        set(${variable} ${value_if_not_fount} PARENT_SCOPE)
Packit cdaae3
    else()
Packit cdaae3
        message(STATUS "Looking for ${prog_to_check_for} - ${variable}")
Packit cdaae3
        set(${variable} ${${variable}} PARENT_SCOPE)
Packit cdaae3
    endif()
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
# check if function func exists in library lib
Packit cdaae3
function(ac_check_lib lib func)
Packit cdaae3
    string(TOUPPER "HAVE_${func}" varname)
Packit cdaae3
    set(CMAKE_REQUIRED_LIBRARIES ${lib})
Packit cdaae3
    check_function_exists(${func} ${varname})
Packit cdaae3
    set(CMAKE_REQUIRED_LIBRARIES)
Packit cdaae3
endfunction()
Packit cdaae3
Packit cdaae3
# check if source compiles without linking
Packit cdaae3
function(ac_try_compile SOURCE VAR)
Packit cdaae3
    set(CMAKE_TMP_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp)
Packit cdaae3
    if(NOT DEFINED "${VAR}")
Packit cdaae3
        file(WRITE 
Packit cdaae3
            "${CMAKE_TMP_DIR}/src.c" 
Packit cdaae3
            "${SOURCE}\n"
Packit cdaae3
        )
Packit cdaae3
        
Packit cdaae3
        if(NOT CMAKE_REQUIRED_QUIET)
Packit cdaae3
            message(STATUS "Performing Test ${VAR}")
Packit cdaae3
        endif()
Packit cdaae3
        # Set up CMakeLists.txt for static library:
Packit cdaae3
        file(WRITE 
Packit cdaae3
            ${CMAKE_TMP_DIR}/CMakeLists.txt
Packit cdaae3
            "add_library(compile STATIC src.c)"
Packit cdaae3
        )
Packit cdaae3
        
Packit cdaae3
        # Configure:
Packit cdaae3
        execute_process(
Packit cdaae3
            COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . 
Packit cdaae3
            WORKING_DIRECTORY ${CMAKE_TMP_DIR}
Packit cdaae3
        )
Packit cdaae3
        
Packit cdaae3
        # Build:
Packit cdaae3
        execute_process(
Packit cdaae3
            COMMAND ${CMAKE_COMMAND} --build ${CMAKE_TMP_DIR}
Packit cdaae3
            RESULT_VARIABLE RESVAR 
Packit cdaae3
            OUTPUT_VARIABLE OUTPUT
Packit cdaae3
            ERROR_VARIABLE OUTPUT
Packit cdaae3
        )
Packit cdaae3
        
Packit cdaae3
        # Set up result:
Packit cdaae3
        if(RESVAR EQUAL 0)
Packit cdaae3
            set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
Packit cdaae3
            if(NOT CMAKE_REQUIRED_QUIET)
Packit cdaae3
                message(STATUS "Performing Test ${VAR} - Success")
Packit cdaae3
            endif()
Packit cdaae3
            
Packit cdaae3
            file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
Packit cdaae3
                "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
Packit cdaae3
                "${OUTPUT}\n"
Packit cdaae3
                "Source file was:\n${SOURCE}\n")
Packit cdaae3
        else()
Packit cdaae3
            if(NOT CMAKE_REQUIRED_QUIET)
Packit cdaae3
                message(STATUS "Performing Test ${VAR} - Failed")
Packit cdaae3
            endif()
Packit cdaae3
            set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
Packit cdaae3
            file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
Packit cdaae3
            "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
Packit cdaae3
            "${OUTPUT}\n"
Packit cdaae3
            "Source file was:\n${SOURCE}\n")
Packit cdaae3
        endif()
Packit cdaae3
    endif()
Packit cdaae3
endfunction()