Salome HOME
Copyright update 2021
[tools/libbatch.git] / CMakeModules / libbatchMacros.cmake
1 # Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 #
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
10 #
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # Lesser General Public License for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 #
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #
22
23 #
24 # Set of macros to identify local shell commands for file deletion,
25 # file copy, etc ... (under Windows and Unix).
26 #
27 MACRO(FIND_LOCAL_COMMAND VAR UNIX_COMMAND WIN32_COMMAND)
28     IF (WIN32)
29         FIND_PROGRAM(${VAR} ${WIN32_COMMAND})
30     ELSE (WIN32)
31         FIND_PROGRAM(${VAR} ${UNIX_COMMAND})
32     ENDIF (WIN32)
33     IF (${VAR})
34         MESSAGE(STATUS "${VAR} found : ${${VAR}}")
35     ELSE (${VAR})
36         MESSAGE(STATUS "${VAR} not found, local submission might not work properly")
37     ENDIF (${VAR})
38 ENDMACRO(FIND_LOCAL_COMMAND)
39
40 MACRO(FIND_LOCAL_COMMAND_WIN32_DEF VAR UNIX_COMMAND WIN32_DEFAULT)
41     IF (WIN32)
42         SET(${VAR} ${WIN32_DEFAULT} CACHE STRING "${VAR}")
43         MESSAGE(STATUS "${VAR} found : using '${${VAR}}' (Windows default)")
44     ELSE (WIN32)
45         FIND_LOCAL_COMMAND(${VAR} ${UNIX_COMMAND} ${WIN32_DEFAULT})
46     ENDIF (WIN32)
47 ENDMACRO(FIND_LOCAL_COMMAND_WIN32_DEF)
48
49 MACRO(EVAL VAR)
50    IF(${ARGN})
51      SET(${VAR} TRUE)
52    ELSE(${ARGN})
53      SET(${VAR} FALSE)
54    ENDIF(${ARGN})
55 ENDMACRO(EVAL)
56
57 MACRO(LIBBATCH_FIND_ALL_LOCAL_COMMANDS)
58   MESSAGE(STATUS "Looking for commands needed for local submission...")
59
60   FIND_LOCAL_COMMAND_WIN32_DEF(LIBBATCH_RM_COMMAND rm del)
61   FIND_LOCAL_COMMAND(LIBBATCH_SH_COMMAND sh cmd.exe)
62   FIND_LOCAL_COMMAND_WIN32_DEF(LIBBATCH_CP_COMMAND cp copy)
63   FIND_LOCAL_COMMAND_WIN32_DEF(LIBBATCH_MKDIR_COMMAND mkdir md)
64   FIND_LOCAL_COMMAND(LIBBATCH_RSH_COMMAND rsh rsh)
65   FIND_LOCAL_COMMAND(LIBBATCH_RCP_COMMAND rcp rcp)
66   FIND_LOCAL_COMMAND(LIBBATCH_SSH_COMMAND ssh plink)
67   FIND_LOCAL_COMMAND(LIBBATCH_SCP_COMMAND scp pscp)
68   FIND_LOCAL_COMMAND(LIBBATCH_RSYNC_COMMAND rsync pscp)
69
70   EVAL (HAS_SH LIBBATCH_SH_COMMAND AND LIBBATCH_CP_COMMAND AND LIBBATCH_RM_COMMAND AND LIBBATCH_MKDIR_COMMAND)
71   EVAL (HAS_RSH LIBBATCH_RSH_COMMAND AND LIBBATCH_RCP_COMMAND)
72   EVAL (HAS_SSH LIBBATCH_SSH_COMMAND AND LIBBATCH_SCP_COMMAND)
73   EVAL (HAS_RSYNC LIBBATCH_SSH_COMMAND AND LIBBATCH_RSYNC_COMMAND)
74   
75   # Mark shell commands as advanced options
76   # and assign the names without the LIBBATCH_ in front:
77   SET (_cmds "RM;SH;CP;MKDIR;RSH;RCP;SSH;SCP;RSYNC")
78   FOREACH(_cmd ${_cmds})    
79     MARK_AS_ADVANCED(LIBBATCH_${_cmd}_COMMAND)
80     SET(${_cmd}_COMMAND ${LIBBATCH_${_cmd}_COMMAND})
81   ENDFOREACH()
82 ENDMACRO()
83
84 #
85 # Display configuration summary
86 #
87 MACRO(LIBBATCH_SUMMARY)
88   MESSAGE(STATUS "")
89   MESSAGE(STATUS "**************** Libbatch Summary *******")
90   MESSAGE(STATUS "")
91   IF (LIBBATCH_LOCAL_SUBMISSION)
92     MESSAGE(STATUS "Local submission .................... Yes")
93   ELSE()
94     MESSAGE(STATUS "Local submission .......... Not requested")
95   ENDIF()
96
97   IF (LIBBATCH_PYTHON_WRAPPING)
98     IF (PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND AND SWIG_FOUND)
99       MESSAGE(STATUS "Python wrapping ..................... Yes")
100     ELSE()
101       MESSAGE(STATUS "Python wrapping ............... Python libs (or Swig) not found")
102     ENDIF()
103   ELSE()
104     MESSAGE(STATUS "Python wrapping ........... Not requested")
105   ENDIF()
106
107   MESSAGE(STATUS "")
108   MESSAGE(STATUS "************** End Summary **************")
109   MESSAGE(STATUS "")
110 ENDMACRO()
111
112 ###
113 # SALOME_CHECK_EQUAL_PATHS(result path1 path2)
114 #  Check if two paths are identical, resolving links. If the paths do not exist a simple
115 #  text comparison is performed.
116 #  result is a boolean.
117 ###
118 MACRO(SALOME_CHECK_EQUAL_PATHS varRes path1 path2)  
119   SET("${varRes}" OFF)
120   IF(EXISTS "${path1}")
121     GET_FILENAME_COMPONENT(_tmp1 "${path1}" REALPATH)
122   ELSE()
123     SET(_tmp1 "${path1}")
124   ENDIF() 
125
126   IF(EXISTS "${path2}")
127     GET_FILENAME_COMPONENT(_tmp2 "${path2}" REALPATH)
128   ELSE()
129     SET(_tmp2 "${path2}")
130   ENDIF() 
131
132   IF("${_tmp1}" STREQUAL "${_tmp2}")
133     SET("${varRes}" ON)
134   ENDIF()
135 #  MESSAGE(${${varRes}})
136 ENDMACRO()
137
138
139 ####
140 # SALOME_FIND_PACKAGE(englobingPackageName standardPackageName modus)
141 # Encapsulate the call to the standard FIND_PACKAGE(standardPackageName) passing all the options
142 # given when calling the command FIND_PACKAGE(customPackageName)
143 # Modus is either MODULE or CONFIG (cf standard FIND_PACKAGE() documentation).
144 # This macro is to be called from within the FindCustomPackage.cmake file.
145 ####
146 MACRO(SALOME_FIND_PACKAGE englobPkg stdPkg mode)
147   # Only bother if the package was not already found:
148   # Some old packages use the lower case version - standard should be to always use
149   # upper case:
150   STRING(TOUPPER ${stdPkg} stdPkgUC)
151   IF(NOT (${stdPkg}_FOUND OR ${stdPkgUC}_FOUND))
152     IF(${englobPkg}_FIND_QUIETLY)
153       SET(_tmp_quiet "QUIET")
154     ELSE()
155       SET(_tmp_quiet)
156     ENDIF()  
157     IF(${englobPkg}_FIND_REQUIRED)
158       SET(_tmp_req "REQUIRED")
159     ELSE()
160       SET(_tmp_req)
161     ENDIF()  
162     IF(${englobPkg}_FIND_VERSION_EXACT)
163       SET(_tmp_exact "EXACT")
164     ELSE()
165       SET(_tmp_exact)
166     ENDIF()
167     IF(${englobPkg}_FIND_COMPONENTS)
168       STRING(REPLACE ";" " " _tmp_compo ${${englobPkg}_FIND_COMPONENTS})
169     ELSE()
170       SET(_tmp_compo)
171     ENDIF()
172
173     # Call the root FIND_PACKAGE():
174     #MESSAGE("blabla ${englobPkg} / ${${englobPkg}_FIND_VERSION_EXACT} / ${stdPkg} ${${englobPkg}_FIND_VERSION} ${_tmp_exact} ${mode}")
175     IF(_tmp_compo)
176       FIND_PACKAGE(${stdPkg} ${${englobPkg}_FIND_VERSION} ${_tmp_exact} ${mode} ${_tmp_quiet} ${_tmp_req} COMPONENTS ${_tmp_compo})
177     ELSE()
178       FIND_PACKAGE(${stdPkg} ${${englobPkg}_FIND_VERSION} ${_tmp_exact} ${mode} ${_tmp_quiet} ${_tmp_req})
179     ENDIF()
180   ENDIF()
181 ENDMACRO()
182
183 ####################################################################"
184 # SALOME_FIND_PACKAGE_DETECT_CONFLICTS(pkg referenceVariable upCount)
185 #    pkg              : name of the system package to be detected
186 #    referenceVariable: variable containing a path that can be browsed up to 
187 # retrieve the package root directory (xxx_ROOT_DIR)
188 #    upCount          : number of times we have to go up from the path <referenceVariable>
189 # to obtain the package root directory.  
190 #   
191 # For example:  SALOME_FIND_PACKAGE_DETECT_CONFLICTS(SWIG SWIG_EXECUTABLE 2) 
192 #
193 # Generic detection (and conflict check) procedure for package XYZ:
194 # 1. Load a potential env variable XYZ_ROOT_DIR as a default choice for the cache entry XYZ_ROOT_DIR
195 #    If empty, load a potential XYZ_ROOT_DIR_EXP as default value (path exposed by another package depending
196 # directly on XYZ)
197 # 2. Invoke FIND_PACKAGE() in this order:
198 #    * in CONFIG mode first (if possible): priority is given to a potential 
199 #    "XYZ-config.cmake" file
200 #    * then switch to the standard MODULE mode, appending on CMAKE_PREFIX_PATH 
201 # the above XYZ_ROOT_DIR variable
202 # 3. Extract the path actually found into a temp variable _XYZ_TMP_DIR
203 # 4. Warn if XYZ_ROOT_DIR is set and doesn't match what was found (e.g. when CMake found the system installation
204 #    instead of what is pointed to by XYZ_ROOT_DIR - happens when a typo in the content of XYZ_ROOT_DIR).
205 # 5. Conflict detection:
206 #    * check the temp variable against a potentially existing XYZ_ROOT_DIR_EXP
207 # 6. Finally expose what was *actually* found in XYZ_ROOT_DIR.  
208 # 7. Specific stuff: for example exposing a prerequisite of XYZ to the rest of the world for future 
209 # conflict detection. This is added after the call to the macro by the callee.
210 #
211 MACRO(SALOME_FIND_PACKAGE_AND_DETECT_CONFLICTS pkg referenceVariable upCount)
212   STRING(TOUPPER ${pkg} pkg_UC)
213
214   # 1. Load environment or any previously detected root dir for the package
215   IF(DEFINED ENV{${pkg_UC}_ROOT_DIR})
216     FILE(TO_CMAKE_PATH "$ENV{${pkg_UC}_ROOT_DIR}" _${pkg_UC}_ROOT_DIR_ENV)
217     SET(_dflt_value "${_${pkg_UC}_ROOT_DIR_ENV}")
218   ELSE()
219     # will be blank if no package was previously loaded
220     SET(_dflt_value "${${pkg_UC}_ROOT_DIR_EXP}")
221   ENDIF()
222
223   #   Make cache entry 
224   SET(${pkg_UC}_ROOT_DIR "${_dflt_value}" CACHE PATH "Path to ${pkg_UC} directory")
225
226   # 2. Find package - config mode first (i.e. looking for XYZ-config.cmake)
227   IF(EXISTS "${${pkg_UC}_ROOT_DIR}")
228     # Hope to find direclty a CMake config file there
229     SET(_CONF_DIR "${${pkg_UC}_ROOT_DIR}/share/cmake") 
230
231     # Try find_package in config mode with a hard-coded guess. This
232     # has the priority.
233     FIND_PACKAGE(${pkg} NO_MODULE QUIET PATHS "${_CONF_DIR}")
234     MARK_AS_ADVANCED(${pkg}_DIR)
235       
236     IF (NOT ${pkg_UC}_FOUND)  
237       SET(CMAKE_PREFIX_PATH "${${pkg_UC}_ROOT_DIR}")
238     ELSE()
239       MESSAGE(STATUS "Found ${pkg} in CONFIG mode!")
240     ENDIF()
241   ENDIF()
242
243   # Otherwise try the standard way (module mode, with the standard CMake Find*** macro):
244   SALOME_FIND_PACKAGE("Salome${pkg}" ${pkg} MODULE)
245   #MESSAGE("dbg ${pkg_UC} / ${PTHREAD_FOUND} / ${${pkg_UC}_FOUND}")
246   # Set the "FOUND" variable for the SALOME wrapper:
247   IF(${pkg_UC}_FOUND OR ${pkg}_FOUND)
248     SET(SALOME${pkg_UC}_FOUND TRUE)
249   ELSE()
250     SET(SALOME${pkg_UC}_FOUND FALSE)
251   ENDIF()
252   
253   IF (${pkg_UC}_FOUND OR ${pkg}_FOUND)
254     # 3. Set the root dir which was finally retained by going up "upDir" times
255     # from the given reference path. The variable "referenceVariable" may be a list
256     # - we take its first element. 
257     #   Note the double de-reference of "referenceVariable":
258     LIST(LENGTH "${${referenceVariable}}" _tmp_len)
259     IF(_tmp_len)
260        LIST(GET "${${referenceVariable}}" 0 _tmp_ROOT_DIR)
261     ELSE()
262        SET(_tmp_ROOT_DIR "${${referenceVariable}}")
263     ENDIF()
264     IF(${upCount})
265       MATH(EXPR _rge "${upCount}-1") 
266       FOREACH(_unused RANGE ${_rge})        
267         GET_FILENAME_COMPONENT(_tmp_ROOT_DIR "${_tmp_ROOT_DIR}" PATH)
268       ENDFOREACH()
269     ENDIF()
270
271     # 4. Warn if CMake found something not located under ENV(XYZ_ROOT_DIR)
272     IF(DEFINED ENV{${pkg_UC}_ROOT_DIR})
273       SALOME_CHECK_EQUAL_PATHS(_res "${_tmp_ROOT_DIR}" "${_${pkg_UC}_ROOT_DIR_ENV}")
274       IF(NOT _res)
275         MESSAGE(WARNING "${pkg} was found, but not at the path given by the "
276             "environment ${pkg_UC}_ROOT_DIR! Is the variable correctly set? "
277             "The two paths are: ${_tmp_ROOT_DIR} and: ${_${pkg_UC}_ROOT_DIR_ENV}")
278         
279       ELSE()
280         MESSAGE(STATUS "${pkg} found directory matches what was specified in the ${pkg_UC}_ROOT_DIR variable, all good!")    
281       ENDIF()
282     ELSE()
283         MESSAGE(STATUS "Variable ${pkg_UC}_ROOT_DIR was not explicitly defined: "
284           "an installation was found anyway: ${_tmp_ROOT_DIR}")
285     ENDIF()
286
287     # 5. Conflict detection
288     # 5.1  From another prerequisite using the package
289     IF(${pkg_UC}_ROOT_DIR_EXP)
290         SALOME_CHECK_EQUAL_PATHS(_res "${_tmp_ROOT_DIR}" "${${pkg_UC}_ROOT_DIR_EXP}") 
291         IF(NOT _res)
292            MESSAGE(WARNING "Warning: ${pkg}: detected version conflicts with a previously found ${pkg}!"
293                             "The two paths are " ${_tmp_ROOT_DIR} " vs " ${${pkg_UC}_ROOT_DIR_EXP})
294         ELSE()
295             MESSAGE(STATUS "${pkg} directory matches what was previously exposed by another prereq, all good!")
296         ENDIF()        
297     ENDIF()
298     
299     # 6. Save the found installation
300     #
301     SET(${pkg_UC}_ROOT_DIR "${_tmp_ROOT_DIR}")
302      
303   ELSE()
304     MESSAGE(STATUS "${pkg} was not found.")  
305   ENDIF()
306 ENDMACRO(SALOME_FIND_PACKAGE_AND_DETECT_CONFLICTS)