STYLE: Nightly Date Stamp
[cmake.git] / Source / kwsys / SharedForward.h.in
blob1ad99746b00aafdb97a5c9814e6eb32050288ae2
1 /*=========================================================================
3 Program: KWSys - Kitware System Library
4 Module: $RCSfile: SharedForward.h.in,v $
6 Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
7 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notices for more information.
13 =========================================================================*/
14 #ifndef @KWSYS_NAMESPACE@_SharedForward_h
15 #define @KWSYS_NAMESPACE@_SharedForward_h
18 This header is used to create a forwarding executable sets up the
19 shared library search path and replaces itself with a real
20 executable. This is useful when creating installations on UNIX with
21 shared libraries that will run from any install directory. Typical
22 usage:
24 #if defined(CMAKE_INTDIR)
25 # define CONFIG_DIR_PRE CMAKE_INTDIR "/"
26 # define CONFIG_DIR_POST "/" CMAKE_INTDIR
27 #else
28 # define CONFIG_DIR_PRE ""
29 # define CONFIG_DIR_POST ""
30 #endif
31 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD "/path/to/foo-build/bin"
32 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD "." CONFIG_DIR_POST
33 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL "../lib/foo-1.2"
34 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD CONFIG_DIR_PRE "foo-real"
35 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL "../lib/foo-1.2/foo-real"
36 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND "--command"
37 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT "--print"
38 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD "--ldd"
39 #if defined(CMAKE_INTDIR)
40 # define @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME CMAKE_INTDIR
41 #endif
42 #include <@KWSYS_NAMESPACE@/SharedForward.h>
43 int main(int argc, char** argv)
45 return @KWSYS_NAMESPACE@_shared_forward_to_real(argc, argv);
48 Specify search and executable paths relative to the forwarding
49 executable location or as full paths. Include no trailing slash.
50 In the case of a multi-configuration build, when CMAKE_INTDIR is
51 defined, the DIR_BUILD setting should point at the directory above
52 the executable (the one containing the per-configuration
53 subdirectory specified by CMAKE_INTDIR). Then PATH_BUILD entries
54 and EXE_BUILD should be specified relative to this location and use
55 CMAKE_INTDIR as necessary. In the above example imagine appending
56 the PATH_BUILD or EXE_BUILD setting to the DIR_BUILD setting. The
57 result should form a valid path with per-configuration subdirectory.
59 Additional paths may be specified in the PATH_BUILD and PATH_INSTALL
60 variables by using comma-separated strings. For example:
62 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD \
63 "." CONFIG_DIR_POST, "/path/to/bar-build" CONFIG_DIR_POST
64 #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL \
65 "../lib/foo-1.2", "../lib/bar-4.5"
67 See the comments below for specific explanations of each macro.
70 /*--------------------------------------------------------------------------*/
72 /* Full path to the directory in which this executable is built. Do
73 not include a trailing slash. */
74 #if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD)
75 # error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD"
76 #endif
77 #if !defined(KWSYS_SHARED_FORWARD_DIR_BUILD)
78 # define KWSYS_SHARED_FORWARD_DIR_BUILD @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD
79 #endif
81 /* Library search path for build tree. */
82 #if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD)
83 # error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD"
84 #endif
85 #if !defined(KWSYS_SHARED_FORWARD_PATH_BUILD)
86 # define KWSYS_SHARED_FORWARD_PATH_BUILD @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD
87 #endif
89 /* Library search path for install tree. */
90 #if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL)
91 # error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL"
92 #endif
93 #if !defined(KWSYS_SHARED_FORWARD_PATH_INSTALL)
94 # define KWSYS_SHARED_FORWARD_PATH_INSTALL @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL
95 #endif
97 /* The real executable to which to forward in the build tree. */
98 #if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD)
99 # error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD"
100 #endif
101 #if !defined(KWSYS_SHARED_FORWARD_EXE_BUILD)
102 # define KWSYS_SHARED_FORWARD_EXE_BUILD @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD
103 #endif
105 /* The real executable to which to forward in the install tree. */
106 #if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL)
107 # error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL"
108 #endif
109 #if !defined(KWSYS_SHARED_FORWARD_EXE_INSTALL)
110 # define KWSYS_SHARED_FORWARD_EXE_INSTALL @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL
111 #endif
113 /* The configuration name with which this executable was built (Debug/Release). */
114 #if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME)
115 # define KWSYS_SHARED_FORWARD_CONFIG_NAME @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME
116 #else
117 # undef KWSYS_SHARED_FORWARD_CONFIG_NAME
118 #endif
120 /* Create command line option to replace executable. */
121 #if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND)
122 # if !defined(KWSYS_SHARED_FORWARD_OPTION_COMMAND)
123 # define KWSYS_SHARED_FORWARD_OPTION_COMMAND @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND
124 # endif
125 #else
126 # undef KWSYS_SHARED_FORWARD_OPTION_COMMAND
127 #endif
129 /* Create command line option to print environment setting and exit. */
130 #if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT)
131 # if !defined(KWSYS_SHARED_FORWARD_OPTION_PRINT)
132 # define KWSYS_SHARED_FORWARD_OPTION_PRINT @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT
133 # endif
134 #else
135 # undef KWSYS_SHARED_FORWARD_OPTION_PRINT
136 #endif
138 /* Create command line option to run ldd or equivalent. */
139 #if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD)
140 # if !defined(KWSYS_SHARED_FORWARD_OPTION_LDD)
141 # define KWSYS_SHARED_FORWARD_OPTION_LDD @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD
142 # endif
143 #else
144 # undef KWSYS_SHARED_FORWARD_OPTION_LDD
145 #endif
147 /*--------------------------------------------------------------------------*/
148 /* Include needed system headers. */
150 #include <limits.h>
151 #include <stdlib.h>
152 #include <string.h>
153 #include <errno.h>
154 #include <stdio.h>
156 #if defined(_WIN32) && !defined(__CYGWIN__)
157 # include <io.h>
158 # include <windows.h>
159 # include <process.h>
160 #else
161 # include <unistd.h>
162 #endif
164 /*--------------------------------------------------------------------------*/
165 /* Configuration for this platform. */
167 /* The path separator for this platform. */
168 #if defined(_WIN32) && !defined(__CYGWIN__)
169 # define KWSYS_SHARED_FORWARD_PATH_SEP ';'
170 # define KWSYS_SHARED_FORWARD_PATH_SLASH '\\'
171 #else
172 # define KWSYS_SHARED_FORWARD_PATH_SEP ':'
173 # define KWSYS_SHARED_FORWARD_PATH_SLASH '/'
174 #endif
175 static const char kwsys_shared_forward_path_sep[2] = {KWSYS_SHARED_FORWARD_PATH_SEP, 0};
176 static const char kwsys_shared_forward_path_slash[2] = {KWSYS_SHARED_FORWARD_PATH_SLASH, 0};
178 /* The maximum length of a file name. */
179 #if defined(PATH_MAX)
180 # define KWSYS_SHARED_FORWARD_MAXPATH PATH_MAX
181 #elif defined(MAXPATHLEN)
182 # define KWSYS_SHARED_FORWARD_MAXPATH MAXPATHLEN
183 #else
184 # define KWSYS_SHARED_FORWARD_MAXPATH 16384
185 #endif
187 /* Select the environment variable holding the shared library runtime
188 search path for this platform and build configuration. Also select
189 ldd command equivalent. */
191 /* Linux */
192 #if defined(__linux)
193 # define KWSYS_SHARED_FORWARD_LDD "ldd"
194 # define KWSYS_SHARED_FORWARD_LDD_N 1
195 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
196 #endif
198 /* FreeBSD */
199 #if defined(__FreeBSD__)
200 # define KWSYS_SHARED_FORWARD_LDD "ldd"
201 # define KWSYS_SHARED_FORWARD_LDD_N 1
202 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
203 #endif
205 /* OSX */
206 #if defined(__APPLE__)
207 # define KWSYS_SHARED_FORWARD_LDD "otool", "-L"
208 # define KWSYS_SHARED_FORWARD_LDD_N 2
209 # define KWSYS_SHARED_FORWARD_LDPATH "DYLD_LIBRARY_PATH"
210 #endif
212 /* AIX */
213 #if defined(_AIX)
214 # define KWSYS_SHARED_FORWARD_LDD "dump", "-H"
215 # define KWSYS_SHARED_FORWARD_LDD_N 2
216 # define KWSYS_SHARED_FORWARD_LDPATH "LIBPATH"
217 #endif
219 /* SUN */
220 #if defined(__sparc)
221 # define KWSYS_SHARED_FORWARD_LDD "ldd"
222 # define KWSYS_SHARED_FORWARD_LDD_N 1
223 # include <sys/isa_defs.h>
224 # if defined(_ILP32)
225 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
226 # elif defined(_LP64)
227 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH_64"
228 # endif
229 #endif
231 /* HP-UX */
232 #if defined(__hpux)
233 # define KWSYS_SHARED_FORWARD_LDD "chatr"
234 # define KWSYS_SHARED_FORWARD_LDD_N 1
235 # if defined(__LP64__)
236 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
237 # else
238 # define KWSYS_SHARED_FORWARD_LDPATH "SHLIB_PATH"
239 # endif
240 #endif
242 /* SGI MIPS */
243 #if defined(__sgi) && defined(_MIPS_SIM)
244 # define KWSYS_SHARED_FORWARD_LDD "ldd"
245 # define KWSYS_SHARED_FORWARD_LDD_N 1
246 # if _MIPS_SIM == _ABIO32
247 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
248 # elif _MIPS_SIM == _ABIN32
249 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARYN32_PATH"
250 # elif _MIPS_SIM == _ABI64
251 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY64_PATH"
252 # endif
253 #endif
255 /* Windows */
256 #if defined(_WIN32)
257 # if defined(__CYGWIN__)
258 # define KWSYS_SHARED_FORWARD_LDD "cygcheck"
259 # define KWSYS_SHARED_FORWARD_LDD_N 1
260 # endif
261 # define KWSYS_SHARED_FORWARD_LDPATH "PATH"
262 #endif
264 /* Guess on this unknown system. */
265 #if !defined(KWSYS_SHARED_FORWARD_LDPATH)
266 # define KWSYS_SHARED_FORWARD_LDD "ldd"
267 # define KWSYS_SHARED_FORWARD_LDD_N 1
268 # define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
269 #endif
271 /*--------------------------------------------------------------------------*/
272 /* Function to convert a logical or relative path to a physical full path. */
273 static int kwsys_shared_forward_realpath(const char* in_path, char* out_path)
275 #if defined(_WIN32) && !defined(__CYGWIN__)
276 /* Implementation for Windows. */
277 DWORD n = GetFullPathName(in_path, KWSYS_SHARED_FORWARD_MAXPATH,
278 out_path, 0);
279 return n > 0 && n <= KWSYS_SHARED_FORWARD_MAXPATH;
280 #else
281 /* Implementation for UNIX. */
282 return realpath(in_path, out_path) != 0;
283 #endif
286 /*--------------------------------------------------------------------------*/
287 /* Function to report a system error message. */
288 static void kwsys_shared_forward_strerror(char* message)
290 #if defined(_WIN32) && !defined(__CYGWIN__)
291 /* Implementation for Windows. */
292 DWORD original = GetLastError();
293 DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
294 FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
295 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
296 message, KWSYS_SHARED_FORWARD_MAXPATH, 0);
297 if(length < 1 || length > KWSYS_SHARED_FORWARD_MAXPATH)
299 /* FormatMessage failed. Use a default message. */
300 _snprintf(message, KWSYS_SHARED_FORWARD_MAXPATH,
301 "Error 0x%X (FormatMessage failed with error 0x%X)",
302 original, GetLastError());
304 #else
305 /* Implementation for UNIX. */
306 strcpy(message, strerror(errno));
307 #endif
310 /*--------------------------------------------------------------------------*/
311 /* Functions to execute a child process. */
312 static void kwsys_shared_forward_execvp(const char* cmd, char* const argv[])
314 #if defined(_MSC_VER)
315 _execvp(cmd, argv);
316 #else
317 execvp(cmd, argv);
318 #endif
321 /*--------------------------------------------------------------------------*/
322 /* Function to get the directory containing the given file or directory. */
323 static void kwsys_shared_forward_dirname(const char* begin, char* result)
325 /* Find the location of the last slash. */
326 int last_slash_index = -1;
327 const char* end = begin + strlen(begin);
328 for(;begin <= end && last_slash_index < 0; --end)
330 if(*end == '/' || *end == '\\')
332 last_slash_index = end-begin;
336 /* Handle each case of the index of the last slash. */
337 if(last_slash_index < 0)
339 /* No slashes. */
340 strcpy(result, ".");
342 else if(last_slash_index == 0)
344 /* Only one leading slash. */
345 strcpy(result, kwsys_shared_forward_path_slash);
347 #if defined(_WIN32)
348 else if(last_slash_index == 2 && begin[1] == ':')
350 /* Only one leading drive letter and slash. */
351 strncpy(result, begin, last_slash_index);
352 result[last_slash_index] = KWSYS_SHARED_FORWARD_PATH_SLASH;
353 result[last_slash_index+1] = 0;
355 #endif
356 else
358 /* A non-leading slash. */
359 strncpy(result, begin, last_slash_index);
360 result[last_slash_index] = 0;
364 /*--------------------------------------------------------------------------*/
365 /* Function to check if a file exists and is executable. */
366 static int kwsys_shared_forward_is_executable(const char* f)
368 #if defined(_MSC_VER)
369 # define KWSYS_SHARED_FORWARD_ACCESS _access
370 #else
371 # define KWSYS_SHARED_FORWARD_ACCESS access
372 #endif
373 #if defined(X_OK)
374 # define KWSYS_SHARED_FORWARD_ACCESS_OK X_OK
375 #else
376 # define KWSYS_SHARED_FORWARD_ACCESS_OK 04
377 #endif
378 if(KWSYS_SHARED_FORWARD_ACCESS(f, KWSYS_SHARED_FORWARD_ACCESS_OK) == 0)
380 return 1;
382 else
384 return 0;
388 /*--------------------------------------------------------------------------*/
389 /* Function to locate the executable currently running. */
390 static int kwsys_shared_forward_self_path(const char* argv0, char* result)
392 /* Check whether argv0 has a slash. */
393 int has_slash = 0;
394 const char* p = argv0;
395 for(;*p && !has_slash; ++p)
397 if(*p == '/' || *p == '\\')
399 has_slash = 1;
403 if(has_slash)
405 /* There is a slash. Use the dirname of the given location. */
406 kwsys_shared_forward_dirname(argv0, result);
407 return 1;
409 else
411 /* There is no slash. Search the PATH for the executable. */
412 const char* path = getenv("PATH");
413 const char* begin = path;
414 const char* end = begin + (begin?strlen(begin):0);
415 const char* first = begin;
416 while(first != end)
418 /* Store the end of this path entry. */
419 const char* last;
421 /* Skip all path separators. */
422 for(;*first && *first == KWSYS_SHARED_FORWARD_PATH_SEP; ++first);
424 /* Find the next separator. */
425 for(last = first;*last && *last != KWSYS_SHARED_FORWARD_PATH_SEP; ++last);
427 /* If we got a non-empty directory, look for the executable there. */
428 if(first < last)
430 /* Determine the length without trailing slash. */
431 int length = last-first;
432 if(*(last-1) == '/' || *(last-1) == '\\')
434 --length;
437 /* Construct the name of the executable in this location. */
438 strncpy(result, first, length);
439 result[length] = KWSYS_SHARED_FORWARD_PATH_SLASH;
440 strcpy(result+(length)+1, argv0);
442 /* Check if it exists and is executable. */
443 if(kwsys_shared_forward_is_executable(result))
445 /* Found it. */
446 result[length] = 0;
447 return 1;
451 /* Move to the next directory in the path. */
452 first = last;
456 /* We could not find the executable. */
457 return 0;
460 /*--------------------------------------------------------------------------*/
461 /* Function to convert a specified path to a full path. If it is not
462 already full, it is taken relative to the self path. */
463 static int kwsys_shared_forward_fullpath(const char* self_path,
464 const char* in_path,
465 char* result,
466 const char* desc)
468 /* Check the specified path type. */
469 if(in_path[0] == '/')
471 /* Already a full path. */
472 strcpy(result, in_path);
474 #if defined(_WIN32)
475 else if(in_path[0] && in_path[1] == ':')
477 /* Already a full path. */
478 strcpy(result, in_path);
480 #endif
481 else
483 /* Relative to self path. */
484 char temp_path[KWSYS_SHARED_FORWARD_MAXPATH];
485 strcpy(temp_path, self_path);
486 strcat(temp_path, kwsys_shared_forward_path_slash);
487 strcat(temp_path, in_path);
488 if(!kwsys_shared_forward_realpath(temp_path, result))
490 if(desc)
492 char msgbuf[KWSYS_SHARED_FORWARD_MAXPATH];
493 kwsys_shared_forward_strerror(msgbuf);
494 fprintf(stderr, "Error converting %s \"%s\" to real path: %s\n",
495 desc, temp_path, msgbuf);
497 return 0;
500 return 1;
503 /*--------------------------------------------------------------------------*/
504 /* Function to compute the library search path and executable name
505 based on the self path. */
506 static int kwsys_shared_forward_get_settings(const char* self_path,
507 char* ldpath, char* exe)
509 /* Possible search paths. */
510 static const char* search_path_build[] = {KWSYS_SHARED_FORWARD_PATH_BUILD, 0};
511 static const char* search_path_install[] = {KWSYS_SHARED_FORWARD_PATH_INSTALL, 0};
513 /* Chosen paths. */
514 const char** search_path;
515 const char* exe_path;
517 /* Get the real name of the build and self paths. */
518 #if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME)
519 char build_path[] = KWSYS_SHARED_FORWARD_DIR_BUILD "/" KWSYS_SHARED_FORWARD_CONFIG_NAME;
520 char self_path_logical[KWSYS_SHARED_FORWARD_MAXPATH];
521 #else
522 char build_path[] = KWSYS_SHARED_FORWARD_DIR_BUILD;
523 const char* self_path_logical = self_path;
524 #endif
525 char build_path_real[KWSYS_SHARED_FORWARD_MAXPATH];
526 char self_path_real[KWSYS_SHARED_FORWARD_MAXPATH];
527 if(!kwsys_shared_forward_realpath(self_path, self_path_real))
529 char msgbuf[KWSYS_SHARED_FORWARD_MAXPATH];
530 kwsys_shared_forward_strerror(msgbuf);
531 fprintf(stderr, "Error converting self path \"%s\" to real path: %s\n",
532 self_path, msgbuf);
533 return 0;
536 /* Check whether we are running in the build tree or an install tree. */
537 if(kwsys_shared_forward_realpath(build_path, build_path_real) &&
538 strcmp(self_path_real, build_path_real) == 0)
540 /* Running in build tree. Use the build path and exe. */
541 search_path = search_path_build;
542 #if defined(_WIN32)
543 exe_path = KWSYS_SHARED_FORWARD_EXE_BUILD ".exe";
544 #else
545 exe_path = KWSYS_SHARED_FORWARD_EXE_BUILD;
546 #endif
548 #if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME)
549 /* Remove the configuration directory from self_path. */
550 kwsys_shared_forward_dirname(self_path, self_path_logical);
551 #endif
553 else
555 /* Running in install tree. Use the install path and exe. */
556 search_path = search_path_install;
557 #if defined(_WIN32)
558 exe_path = KWSYS_SHARED_FORWARD_EXE_INSTALL ".exe";
559 #else
560 exe_path = KWSYS_SHARED_FORWARD_EXE_INSTALL;
561 #endif
563 #if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME)
564 /* Use the original self path directory. */
565 strcpy(self_path_logical, self_path);
566 #endif
569 /* Construct the runtime search path. */
571 const char** dir;
572 for(dir = search_path; *dir; ++dir)
574 /* Add seperator between path components. */
575 if(dir != search_path)
577 strcat(ldpath, kwsys_shared_forward_path_sep);
580 /* Add this path component. */
581 if(!kwsys_shared_forward_fullpath(self_path_logical, *dir,
582 ldpath+strlen(ldpath),
583 "runtime path entry"))
585 return 0;
590 /* Construct the executable location. */
591 if(!kwsys_shared_forward_fullpath(self_path_logical, exe_path, exe,
592 "executable file"))
594 return 0;
596 return 1;
599 /*--------------------------------------------------------------------------*/
600 /* Function to print why execution of a command line failed. */
601 static void kwsys_shared_forward_print_failure(char** argv)
603 char msg[KWSYS_SHARED_FORWARD_MAXPATH];
604 char** arg = argv;
605 kwsys_shared_forward_strerror(msg);
606 fprintf(stderr, "Error running");
607 for(; *arg; ++arg)
609 fprintf(stderr, " \"%s\"", *arg);
611 fprintf(stderr, ": %s\n", msg);
614 /* Static storage space to store the updated environment variable. */
615 static char kwsys_shared_forward_ldpath[KWSYS_SHARED_FORWARD_MAXPATH*16] = KWSYS_SHARED_FORWARD_LDPATH "=";
617 /*--------------------------------------------------------------------------*/
618 /* Main driver function to be called from main. */
619 static int @KWSYS_NAMESPACE@_shared_forward_to_real(int argc, char** argv)
621 /* Get the directory containing this executable. */
622 char self_path[KWSYS_SHARED_FORWARD_MAXPATH];
623 if(kwsys_shared_forward_self_path(argv[0], self_path))
625 /* Found this executable. Use it to get the library directory. */
626 char exe[KWSYS_SHARED_FORWARD_MAXPATH];
627 if(kwsys_shared_forward_get_settings(self_path,
628 kwsys_shared_forward_ldpath, exe))
630 /* Append the old runtime search path. */
631 const char* old_ldpath = getenv(KWSYS_SHARED_FORWARD_LDPATH);
632 if(old_ldpath)
634 strcat(kwsys_shared_forward_ldpath, kwsys_shared_forward_path_sep);
635 strcat(kwsys_shared_forward_ldpath, old_ldpath);
638 /* Store the environment variable. */
639 putenv(kwsys_shared_forward_ldpath);
641 #if defined(KWSYS_SHARED_FORWARD_OPTION_COMMAND)
642 /* Look for the command line replacement option. */
643 if(argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_COMMAND) == 0)
645 if(argc > 2)
647 /* Use the command line given. */
648 strcpy(exe, argv[2]);
649 argv += 2;
650 argc -= 2;
652 else
654 /* The option was not given an executable. */
655 fprintf(stderr, "Option " KWSYS_SHARED_FORWARD_OPTION_COMMAND
656 " must be followed by a command line.\n");
657 return 1;
660 #endif
662 #if defined(KWSYS_SHARED_FORWARD_OPTION_PRINT)
663 /* Look for the print command line option. */
664 if(argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_PRINT) == 0)
666 fprintf(stdout, "%s\n", kwsys_shared_forward_ldpath);
667 fprintf(stdout, "%s\n", exe);
668 return 0;
670 #endif
672 #if defined(KWSYS_SHARED_FORWARD_OPTION_LDD)
673 /* Look for the ldd command line option. */
674 if(argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_LDD) == 0)
676 # if defined(KWSYS_SHARED_FORWARD_LDD)
677 /* Use the named ldd-like executable and arguments. */
678 char* ldd_argv[] = {KWSYS_SHARED_FORWARD_LDD, 0, 0};
679 ldd_argv[KWSYS_SHARED_FORWARD_LDD_N] = exe;
680 kwsys_shared_forward_execvp(ldd_argv[0], ldd_argv);
682 /* Report why execution failed. */
683 kwsys_shared_forward_print_failure(ldd_argv);
684 return 1;
685 # else
686 /* We have no ldd-like executable available on this platform. */
687 fprintf(stderr, "No ldd-like tool is known to this executable.\n");
688 return 1;
689 # endif
691 #endif
693 /* Replace this process with the real executable. */
694 argv[0] = exe;
695 kwsys_shared_forward_execvp(argv[0], argv);
697 /* Report why execution failed. */
698 kwsys_shared_forward_print_failure(argv);
700 else
702 /* Could not convert self path to the library directory. */
705 else
707 /* Could not find this executable. */
708 fprintf(stderr, "Error locating executable \"%s\".\n", argv[0]);
711 /* Avoid unused argument warning. */
712 (void)argc;
714 /* Exit with failure. */
715 return 1;
718 #else
719 # error "@KWSYS_NAMESPACE@/SharedForward.h should be included only once."
720 #endif