Prefer C library wrappers over C headers, where possible.
[ginac.git] / cmake / modules / FindGiNaC.cmake
1 # GINAC_FOUND           CiNaC has been successfully found
2 # GINAC_INCLUDE_DIRS    the include directories
3 # GINAC_LIBRARIES       GiNaC library and its dependencies
4
5 if (GINAC_INCLUDE_DIRS AND GINAC_LIBRARIES)
6         set(GINAC_FIND_QUIETLY TRUE)
7 endif()
8
9 function(_ginac_headers_version _out_major _out_minor _out_patch _version_h)
10         file(STRINGS ${_version_h} _ginac_vinfo REGEX "^#define[\t ]+GINACLIB_.*_VERSION.*")
11         if (NOT _ginac_vinfo)
12                 message(FATAL_ERROR "include file ${_version_h} does not exist")
13         endif()
14         string(REGEX REPLACE "^.*GINACLIB_MAJOR_VERSION[ \t]+([0-9]+).*" "\\1" ${_out_major} "${_ginac_vinfo}")
15         string(REGEX REPLACE "^.*GINACLIB_MINOR_VERSION[ \t]+([0-9]+).*" "\\1" ${_out_minor} "${_ginac_vinfo}")
16         string(REGEX REPLACE "^.*GINACLIB_MICRO_VERSION[ \t]+([0-9]+).*" "\\1" ${_out_patch} "${_ginac_vinfo}")
17         if (NOT ${_out_major} MATCHES "[0-9]+")
18                 message(FATAL_ERROR "failed to determine GINACLIB_MAJOR_VERSION, "
19                                     "expected a number, got ${${_out_major}}")
20         endif()
21         if (NOT ${_out_minor} MATCHES "[0-9]+")
22                 message(FATAL_ERROR "failed to determine GINACLIB_MINOR_VERSION, "
23                                     "expected a number, got ${${_out_minor}}")
24         endif()
25         if (NOT ${_out_patch} MATCHES "[0-9]+")
26                 message(FATAL_ERROR "failed to determine GINACLIB_MINOR_VERSION, "
27                                     "expected a number, got ${${_out_patch}}")
28         endif()
29         set(${_out_major} ${${_out_major}} PARENT_SCOPE)
30         set(${_out_minor} ${${_out_minor}} PARENT_SCOPE)
31         set(${_out_patch} ${${_out_patch}} PARENT_SCOPE)
32 endfunction()
33
34 set(GINAC_FOUND)
35 set(GINAC_INCLUDE_DIRS)
36 set(GINAC_LIBRARIES)
37 set(GINAC_LIBRARY_DIRS)
38 set(GINAC_VERSION)
39
40 include(FindPkgConfig)
41 find_package(CLN 1.2.2)
42
43 if (PKG_CONFIG_FOUND)
44         pkg_check_modules(_ginac ginac)
45 else()
46         set(_ginac_LIBRARIES ginac cln gmp)
47 endif()
48
49 if (NOT CLN_FOUND)
50         set(GINAC_INCLUDE_DIRS GINAC-NOTFOUND)
51         set(GINAC_LIBRARIES GINAC-NOTFOUND)
52 else()
53         find_path(_ginac_include_dir NAMES ginac/ginac.h
54                                      HINTS ${_ginac_INCLUDE_DIRS}
55                                            $ENV{GINAC_DIR}/include)
56         if (_ginac_include_dir)
57                 set(GINAC_INCLUDE_DIRS ${_ginac_include_dir}
58                                        ${_ginac_INCLUDE_DIRS}
59                                        ${CLN_INCLUDE_DIR})
60                 list(REMOVE_DUPLICATES GINAC_INCLUDE_DIRS)
61         else()
62                 set(GINAC_INCLUDE_DIRS GINAC-NOTFOUND)
63                 set(GINAC_LIBRARIES GINAC-NOTFOUND)
64                 if (NOT GINAC_FIND_QUIETLY)
65                         message(ERROR "couldn't find ginac.h")
66                 endif()
67         endif()
68
69         if (GINAC_INCLUDE_DIRS)
70                 find_library(_ginac_lib NAMES libginac ginac
71                                         HINTS ${_ginac_LIBRARY_DIRS}
72                                               $ENV{GINAC_DIR}/lib)
73                 if (_ginac_lib)
74                         set(GINAC_LIBRARIES ${_ginac_lib} ${CLN_LIBRARIES})
75                         list(REMOVE_DUPLICATES GINAC_LIBRARIES)
76                 else()
77                         set(GINAC_LIBRARIES GINAC-NOTFOUND)
78                         set(GINAC_INCLUDE_DIRS GINAC-NOTFOUND)
79                         if (NOT GINAC_FIND_QUIETLY)
80                                 message(ERROR "couldn't find libginac")
81                         endif()
82                 endif()
83         endif()
84 endif()
85
86 if (GINAC_INCLUDE_DIRS)
87         _ginac_headers_version(GINACLIB_MAJOR_VERSION
88                                GINACLIB_MINOR_VERSION
89                                GINACLIB_MICRO_VERSION
90                                ${_ginac_include_dir}/ginac/version.h)
91         set(GINAC_VERSION ${GINACLIB_MAJOR_VERSION}.${GINACLIB_MINOR_VERSION}.${GINACLIB_MICRO_VERSION})
92         # Check if the version reported by pkg-config is the same
93         # as the one read from the header. This prevents us from
94         # picking the wrong version of GINAC (say, if several versions
95         # are installed)
96         if (PKG_CONFIG_FOUND AND NOT GINAC_VERSION VERSION_EQUAL _ginac_VERSION)
97                 if (NOT CLN_FIND_QUIETLY)
98                         message(ERROR "pkg-config and version.h disagree, "
99                                       "${_ginac_VERSION} vs ${GINAC_VERSION}, "
100                                       "please check your installation")
101                 endif()
102                 set(GINAC_LIBRARIES GINAC-NOTFOUND)
103                 set(GINAC_INCLUDE_DIRS GINAC-NOTFOUND)
104                 set(GINAC_LIBRARY_DIRS)
105                 set(GINAC_VERSION)
106         endif()
107 endif()
108
109 # Check if the version embedded into the library is the same as the one in the headers.
110 if (GINAC_INCLUDE_DIRS AND GINAC_LIBRARIES AND NOT CMAKE_CROSSCOMPILING)
111         include(CheckCXXSourceRuns)
112         set(_save_required_includes ${CMAKE_REQUIRED_INCLUDES})
113         set(_save_required_libraries ${CMAKE_REQUIRED_LIBRARIES})
114         set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${GINAC_INCLUDE_DIRS})
115         set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${GINAC_LIBRARIES})
116         check_cxx_source_runs("
117                 #include <ginac/version.h>
118                 #include <cln/version.h>
119                 #include <cstdio>
120                 int main() {
121                         return (CL_VERSION_MAJOR == cln::version_major) &&
122                                (CL_VERSION_MINOR == cln::version_minor) &&
123                                (CL_VERSION_PATCHLEVEL == cln::version_patchlevel) &&
124                                (GINACLIB_MAJOR_VERSION == GiNaC::version_major) &&
125                                (GINACLIB_MINOR_VERSION == GiNaC::version_minor) &&
126                                (GINACLIB_MICRO_VERSION == GiNaC::version_micro) ? 0 : 1;
127                 }
128                 "
129                 _ginac_version_matches)
130         set(CMAKE_REQUIRED_LIBRARIES ${_save_required_libraries})
131         set(CMAKE_REQUIRED_INCLUDES ${_save_required_includes})
132         if (NOT _ginac_version_matches)
133                 if (NOT GINAC_FIND_QUIETLY)
134                         message(ERROR "header version differs from the library one, "
135                                       "please check your installation.")
136                 endif()
137                 set(GINAC_INCLUDE_DIRS GINAC-NOTFOUND)
138                 set(GINAC_LIBRARIES GINAC_NOTFOUND)
139                 set(GINAC_LIBRARY_DIRS)
140                 set(GINAC_VERSION)
141         endif()
142 endif()
143
144 if (GINAC_LIBRARIES AND GINAC_INCLUDE_DIRS)
145         set(_ginac_library_dirs)
146         foreach(_l ${GINAC_LIBRARIES})
147                 get_filename_component(_d "${_l}" PATH)
148                 list(APPEND _ginac_library_dirs "${_d}")
149         endforeach()
150         list(REMOVE_DUPLICATES _ginac_library_dirs)
151         set(GINAC_LIBRARY_DIRS ${_ginac_library_dirs})
152 endif()
153
154 include(FindPackageHandleStandardArgs)
155 FIND_PACKAGE_HANDLE_STANDARD_ARGS(GiNaC REQUIRED_VARS GINAC_LIBRARIES GINAC_INCLUDE_DIRS
156                                         VERSION_VAR GINAC_VERSION)
157