Salome HOME
Build SIMANIO on windows using Microsoft Visual Studio 2010.
[tools/simanio.git] / CMakeModules / SimanIOMacros.cmake
1 # Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19
20 ###
21 # SALOME_CHECK_EQUAL_PATHS(result path1 path2)
22 #  Check if two paths are identical, resolving links. If the paths do not exist a simple
23 #  text comparison is performed.
24 #  result is a boolean.
25 ###
26 MACRO(SALOME_CHECK_EQUAL_PATHS varRes path1 path2)  
27   SET("${varRes}" OFF)
28   IF(EXISTS "${path1}")
29     GET_FILENAME_COMPONENT(_tmp1 "${path1}" REALPATH)
30   ELSE()
31     SET(_tmp1 "${path1}")
32   ENDIF() 
33
34   IF(EXISTS "${path2}")
35     GET_FILENAME_COMPONENT(_tmp2 "${path2}" REALPATH)
36   ELSE()
37     SET(_tmp2 "${path2}")
38   ENDIF() 
39
40   IF("${_tmp1}" STREQUAL "${_tmp2}")
41     SET("${varRes}" ON)
42   ENDIF()
43 #  MESSAGE(${${varRes}})
44 ENDMACRO()
45
46 ####
47 # SALOME_FIND_PACKAGE(englobingPackageName standardPackageName modus [onlyTryQuietly])
48 #
49 # example:  SALOME_FIND_PACKAGE(SalomeVTK VTK CONFIG)
50 #
51 # Encapsulate the call to the standard FIND_PACKAGE(standardPackageName) passing all the options
52 # given when calling the command FIND_PACKAGE(SimanIOXyz). Those options are stored implicitly in 
53 # CMake variables: Xyz_FIND_QUIETLY, Xyz_FIND_REQUIRED, etc ...
54
55 # If a list of components was specified when invoking the initial FIND_PACKAGE(SimanIOXyz ...) this is 
56 # also handled properly.
57 #
58 # Modus is either MODULE or CONFIG (cf standard FIND_PACKAGE() documentation).
59 # The last argument is optional and if set to TRUE will force the search to be OPTIONAL and QUIET.
60 # If the package is looked for in CONFIG mode, the standard system paths are skipped. If you still want a 
61 # system installation to be found in this mode, you have to set the ROOT_DIR variable explicitly to /usr (for
62 # example). 
63 #  
64 # This macro is to be called from within the FindSimanIOXyz.cmake files (where Xyz is some package to be detected).
65 #
66 ####
67 MACRO(SALOME_FIND_PACKAGE englobPkg stdPkg mode)
68   SET(_OPT_ARG ${ARGV3})
69   # Only bother if the package was not already found:
70   # Some old packages use the lower case version - standard should be to always use
71   # upper case:
72   STRING(TOUPPER ${stdPkg} stdPkgUC)
73   IF(NOT (${stdPkg}_FOUND OR ${stdPkgUC}_FOUND))
74     IF(${englobPkg}_FIND_QUIETLY OR _OPT_ARG)
75       SET(_tmp_quiet "QUIET")
76     ELSE()
77       SET(_tmp_quiet)
78     ENDIF()  
79     IF(${englobPkg}_FIND_REQUIRED AND NOT _OPT_ARG)
80       SET(_tmp_req "REQUIRED")
81     ELSE()
82       SET(_tmp_req)
83     ENDIF()  
84     IF(${englobPkg}_FIND_VERSION_EXACT)
85       SET(_tmp_exact "EXACT")
86     ELSE()
87       SET(_tmp_exact)
88     ENDIF()
89
90     # Call the CMake FIND_PACKAGE() command:    
91     STRING(TOLOWER ${stdPkg} _pkg_lc)
92     IF(("${mode}" STREQUAL "NO_MODULE") OR ("${mode}" STREQUAL "CONFIG"))
93       # Hope to find direclty a CMake config file, indicating the SALOME CMake file
94       # paths (the command already looks in places like "share/cmake", etc ... by default)
95       # Note the options NO_CMAKE_BUILDS_PATH, NO_CMAKE_PACKAGE_REGISTRY to avoid (under Windows)
96       # looking into a previous CMake build done via a GUI, or into the Win registry.
97       # NO_CMAKE_SYSTEM_PATH and NO_SYSTEM_ENVIRONMENT_PATH ensure any _system_ files like 'xyz-config.cmake' 
98       # don't get loaded (typically Boost). To force their loading, set the XYZ_ROOT_DIR variable to '/usr'. 
99       # See documentation of FIND_PACKAGE() for full details.
100       
101       # Do we need to call the signature using components?
102       IF(${englobPkg}_FIND_COMPONENTS)
103         FIND_PACKAGE(${stdPkg} ${${englobPkg}_FIND_VERSION} ${_tmp_exact} 
104               NO_MODULE ${_tmp_quiet} ${_tmp_req} COMPONENTS ${${englobPkg}_FIND_COMPONENTS}
105               NO_CMAKE_BUILDS_PATH NO_CMAKE_PACKAGE_REGISTRY NO_CMAKE_SYSTEM_PACKAGE_REGISTRY NO_CMAKE_SYSTEM_PATH
106                 NO_SYSTEM_ENVIRONMENT_PATH)
107       ELSE()
108         FIND_PACKAGE(${stdPkg} ${${englobPkg}_FIND_VERSION} ${_tmp_exact} 
109               NO_MODULE ${_tmp_quiet} ${_tmp_req}
110               NO_CMAKE_BUILDS_PATH NO_CMAKE_PACKAGE_REGISTRY NO_CMAKE_SYSTEM_PACKAGE_REGISTRY NO_CMAKE_SYSTEM_PATH
111                  NO_SYSTEM_ENVIRONMENT_PATH)
112       ENDIF()
113       MARK_AS_ADVANCED(${stdPkg}_DIR)
114       
115     ELSEIF("${mode}" STREQUAL "MODULE")
116     
117       # Do we need to call the signature using components?
118       IF(${englobPkg}_FIND_COMPONENTS)
119         FIND_PACKAGE(${stdPkg} ${${englobPkg}_FIND_VERSION} ${_tmp_exact} 
120               MODULE ${_tmp_quiet} ${_tmp_req} COMPONENTS ${${englobPkg}_FIND_COMPONENTS})
121       ELSE()
122         FIND_PACKAGE(${stdPkg} ${${englobPkg}_FIND_VERSION} ${_tmp_exact} 
123               MODULE ${_tmp_quiet} ${_tmp_req})
124       ENDIF()
125       
126     ELSE()
127     
128       MESSAGE(FATAL_ERROR "Invalid mode argument in the call to the macro SALOME_FIND_PACKAGE. Should be CONFIG or MODULE.")
129       
130     ENDIF()
131     
132   ENDIF()
133 ENDMACRO()
134
135
136 ####################################################################
137 # SALOME_FIND_PACKAGE_DETECT_CONFLICTS(pkg referenceVariable upCount)
138 #    pkg              : name of the system package to be detected
139 #    referenceVariable: variable containing a path that can be browsed up to 
140 # retrieve the package root directory (xxx_ROOT_DIR)
141 #    upCount          : number of times we have to go up from the path <referenceVariable>
142 # to obtain the package root directory.
143 #   
144 # For example:  SALOME_FIND_PACKAGE_DETECT_CONFLICTS(SWIG SWIG_EXECUTABLE 2) 
145 #
146 # Generic detection (and conflict check) procedure for package XYZ:
147 # 1. Load a potential env variable XYZ_ROOT_DIR as a default choice for the cache entry XYZ_ROOT_DIR
148 #    If empty, load a potential XYZ_ROOT_DIR_EXP as default value (path exposed by another package depending
149 # directly on XYZ)
150 # 2. Invoke FIND_PACKAGE() in this order:
151 #    * in CONFIG mode first (if possible): priority is given to a potential 
152 #    "XYZ-config.cmake" file
153 #    * then switch to the standard MODULE mode, appending on CMAKE_PREFIX_PATH 
154 # the above XYZ_ROOT_DIR variable
155 # 3. Extract the path actually found into a temp variable _XYZ_TMP_DIR
156 # 4. Warn if XYZ_ROOT_DIR is set and doesn't match what was found (e.g. when CMake found the system installation
157 #    instead of what is pointed to by XYZ_ROOT_DIR - happens when a typo in the content of XYZ_ROOT_DIR).
158 # 5. Conflict detection:
159 #    * check the temp variable against a potentially existing XYZ_ROOT_DIR_EXP
160 # 6. Finally expose what was *actually* found in XYZ_ROOT_DIR.  
161 # 7. Specific stuff: for example exposing a prerequisite of XYZ to the rest of the world for future 
162 # conflict detection. This is added after the call to the macro by the callee.
163 #
164 MACRO(SALOME_FIND_PACKAGE_AND_DETECT_CONFLICTS pkg referenceVariable upCount)
165   ##
166   ## 0. Initialization
167   ##
168   
169   # Package name, upper case
170   STRING(TOUPPER ${pkg} pkg_UC)
171
172   ##
173   ## 1. Load environment or any previously detected root dir for the package
174   ##
175   IF(DEFINED ENV{${pkg_UC}_ROOT_DIR})
176     FILE(TO_CMAKE_PATH "$ENV{${pkg_UC}_ROOT_DIR}" _${pkg_UC}_ROOT_DIR_ENV)
177     SET(_dflt_value "${_${pkg_UC}_ROOT_DIR_ENV}")
178   ELSE()
179     # will be blank if no package was previously loaded:
180     SET(_dflt_value "${${pkg_UC}_ROOT_DIR_EXP}")
181   ENDIF()
182
183   # Detect if the variable has been set on the command line or elsewhere:
184   IF(DEFINED ${pkg_UC}_ROOT_DIR)
185      SET(_var_already_there TRUE)
186   ELSE()
187      SET(_var_already_there FALSE)
188   ENDIF()
189   #   Make cache entry 
190   SET(${pkg_UC}_ROOT_DIR "${_dflt_value}" CACHE PATH "Path to ${pkg_UC} directory")
191
192   ##
193   ## 2. Find package - try CONFIG mode first (i.e. looking for XYZ-config.cmake)
194   ##
195   
196   # Override the variable - don't append to it, as it would give precedence
197   # to what was stored there before!  
198   SET(CMAKE_PREFIX_PATH "${${pkg_UC}_ROOT_DIR}")
199     
200   # Try find_package in config mode. This has the priority, but is 
201   # performed QUIET and not REQUIRED:
202   SALOME_FIND_PACKAGE("Salome${pkg}" ${pkg} NO_MODULE TRUE)
203   
204   IF (${pkg_UC}_FOUND OR ${pkg}_FOUND)
205     MESSAGE(STATUS "Found ${pkg} in CONFIG mode!")
206   ENDIF()
207
208   # Otherwise try the standard way (module mode, with the standard CMake Find*** macro):
209   # We do it quietly to produce our own error message, except if we are in debug mode:
210   IF(SALOME_CMAKE_DEBUG)
211     SALOME_FIND_PACKAGE("Salome${pkg}" ${pkg} MODULE FALSE)
212   ELSE()
213     SALOME_FIND_PACKAGE("Salome${pkg}" ${pkg} MODULE TRUE)
214   ENDIF()
215   
216   # Set the "FOUND" variable for the SALOME wrapper:
217   IF(${pkg_UC}_FOUND OR ${pkg}_FOUND)
218     SET(SALOME${pkg_UC}_FOUND TRUE)
219   ELSE()
220     SET(SALOME${pkg_UC}_FOUND FALSE)
221     IF(NOT Salome${pkg}_FIND_QUIETLY)
222       IF(Salome${pkg}_FIND_REQUIRED)
223          MESSAGE(FATAL_ERROR "Package ${pkg} couldn't be found - did you set the corresponing root dir correctly? "
224          "It currently contains ${pkg_UC}_ROOT_DIR=${${pkg_UC}_ROOT_DIR}  "
225          "Append -DSALOME_CMAKE_DEBUG=ON on the command line if you want to see the original CMake error.")
226       ELSE()
227          MESSAGE(WARNING "Package ${pkg} couldn't be found - did you set the corresponing root dir correctly? "
228          "It currently contains ${pkg_UC}_ROOT_DIR=${${pkg_UC}_ROOT_DIR}  "
229          "Append -DSALOME_CMAKE_DEBUG=ON on the command line if you want to see the original CMake error.")
230       ENDIF()
231     ENDIF()
232   ENDIF()
233   
234   IF (${pkg_UC}_FOUND OR ${pkg}_FOUND)
235     ## 3. Set the root dir which was finally retained by going up "upDir" times
236     ## from the given reference path. The variable "referenceVariable" may be a list.
237     ## In this case we take its first element. 
238     
239     # First test if the variable exists, warn otherwise:
240     IF(NOT DEFINED ${referenceVariable})
241       MESSAGE(WARNING "${pkg}: the reference variable '${referenceVariable}' used when calling the macro "
242       "SALOME_FIND_PACKAGE_AND_DETECT_CONFLICTS() is not defined.")
243     ENDIF()
244     
245     LIST(LENGTH ${referenceVariable} _tmp_len)
246     IF(_tmp_len)
247        LIST(GET ${referenceVariable} 0 _tmp_ROOT_DIR)
248     ELSE()
249        #  Note the double de-reference of "referenceVariable":
250        SET(_tmp_ROOT_DIR "${${referenceVariable}}")
251     ENDIF()
252     IF(${upCount}) 
253       FOREACH(_unused RANGE 1 ${upCount})        
254         GET_FILENAME_COMPONENT(_tmp_ROOT_DIR "${_tmp_ROOT_DIR}" PATH)
255       ENDFOREACH()
256     ENDIF()
257
258     ##
259     ## 4. Warn if CMake found something not located under ENV(XYZ_ROOT_DIR)
260     ##
261     IF(DEFINED ENV{${pkg_UC}_ROOT_DIR})
262       SALOME_CHECK_EQUAL_PATHS(_res "${_tmp_ROOT_DIR}" "${_${pkg_UC}_ROOT_DIR_ENV}")
263       IF(NOT _res)
264         MESSAGE(WARNING "${pkg} was found, but not at the path given by the "
265             "environment ${pkg_UC}_ROOT_DIR! Is the variable correctly set? "
266             "The two paths are: ${_tmp_ROOT_DIR} and: ${_${pkg_UC}_ROOT_DIR_ENV}")
267         
268       ELSE()
269         MESSAGE(STATUS "${pkg} found directory matches what was specified in the ${pkg_UC}_ROOT_DIR variable, all good!")    
270       ENDIF()
271     ELSE()
272         IF(NOT _var_already_there) 
273           MESSAGE(STATUS "Variable ${pkg_UC}_ROOT_DIR was not explicitly defined. "
274           "An installation was found anyway: ${_tmp_ROOT_DIR}")
275         ENDIF()
276     ENDIF()
277
278     ##
279     ## 5. Conflict detection
280     ##     From another prerequisite using the package:
281     ##
282     IF(${pkg_UC}_ROOT_DIR_EXP)
283         SALOME_CHECK_EQUAL_PATHS(_res "${_tmp_ROOT_DIR}" "${${pkg_UC}_ROOT_DIR_EXP}") 
284         IF(NOT _res)
285            MESSAGE(WARNING "Warning: ${pkg}: detected version conflicts with a previously found ${pkg}!"
286                            " The two paths are " ${_tmp_ROOT_DIR} " vs " ${${pkg_UC}_ROOT_DIR_EXP})
287         ELSE()
288             MESSAGE(STATUS "${pkg} directory matches what was previously exposed by another prereq, all good!")
289         ENDIF()        
290     ENDIF()
291     
292     ##
293     ## 6. Save the detected installation
294     ##
295     SET(${pkg_UC}_ROOT_DIR "${_tmp_ROOT_DIR}")
296      
297   ELSE()
298     MESSAGE(STATUS "${pkg} was not found.")  
299   ENDIF()
300   
301   SET(Salome${pkg}_FOUND "${pkg}_FOUND")
302 ENDMACRO(SALOME_FIND_PACKAGE_AND_DETECT_CONFLICTS)