1 /*
2 * Copyright (c) 2006-2007 Los Alamos National Security, LLC. All rights
3 * reserved.
4 * Copyright (c) 2007-2010 Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2007 Sun Microsystem, Inc. All rights reserved.
6 * Copyright (c) 2010 Sandia National Laboratories. All rights reserved.
7 * $COPYRIGHT$
8 *
9 * Additional copyrights may follow
10 *
11 * $HEADER$
12 *
13 */
14
15 #include "opal_config.h"
16
17 #include <string.h>
18
19 #include "opal/util/os_path.h"
20 #include "opal/mca/installdirs/base/base.h"
21 #include "opal/mca/installdirs/installdirs.h"
22
23 /* Support both ${name} and @{name} forms. The latter allows us to
24 pass values through AC_SUBST without being munged by m4 (e.g., if
25 we want to pass "@{libdir}" and not have it replaced by m4 to be
26 whatever the actual value of the shell variable is. */
27 #define EXPAND_STRING(name) EXPAND_STRING2(name, name)
28
29 #define EXPAND_STRING2(ompiname, fieldname) \
30 do { \
31 if (NULL != (start_pos = strstr(retval, "${" #fieldname "}"))) { \
32 tmp = retval; \
33 *start_pos = '\0'; \
34 end_pos = start_pos + strlen("${" #fieldname "}"); \
35 asprintf(&retval, "%s%s%s", tmp, \
36 opal_install_dirs.ompiname + destdir_offset, \
37 end_pos); \
38 free(tmp); \
39 changed = true; \
40 } else if (NULL != (start_pos = strstr(retval, "@{" #fieldname "}"))) { \
41 tmp = retval; \
42 *start_pos = '\0'; \
43 end_pos = start_pos + strlen("@{" #fieldname "}"); \
44 asprintf(&retval, "%s%s%s", tmp, \
45 opal_install_dirs.ompiname + destdir_offset, \
46 end_pos); \
47 free(tmp); \
48 changed = true; \
49 } \
50 } while (0)
51
52
53 /*
54 * Read the lengthy comment below to understand the value of the
55 * is_setup parameter.
56 */
57 static char *
opal_install_dirs_expand_internal(const char * input,bool is_setup)58 opal_install_dirs_expand_internal(const char* input, bool is_setup)
59 {
60 size_t len, i;
61 bool needs_expand = false;
62 char *retval = NULL;
63 char *destdir = NULL;
64 size_t destdir_offset = 0;
65
66 /* This is subtle, and worth explaining.
67
68 If we substitute in any ${FIELD} values, we need to prepend it
69 with the value of the $OPAL_DESTDIR environment variable -- if
70 it is set.
71
72 We need to handle at least three cases properly (assume that
73 configure was invoked with --prefix=/opt/openmpi and no other
74 directory specifications, and OPAL_DESTDIR is set to
75 /tmp/buildroot):
76
77 1. Individual directories, such as libdir. These need to be
78 prepended with DESTDIR. I.e., return
79 /tmp/buildroot/opt/openmpi/lib.
80
81 2. Compiler flags that have ${FIELD} values embedded in them.
82 For example, consider if a wrapper compiler data file
83 contains the line:
84
85 preprocessor_flags=-DMYFLAG="${prefix}/share/randomthingy/"
86
87 The value we should return is:
88
89 -DMYFLAG="/tmp/buildroot/opt/openmpi/share/randomthingy/"
90
91 3. Compiler flags that do not have any ${FIELD} values.
92 For example, consider if a wrapper compiler data file
93 contains the line:
94
95 preprocessor_flags=-pthread
96
97 The value we should return is:
98
99 -pthread
100
101 Note, too, that this OPAL_DESTDIR futzing only needs to occur
102 during opal_init(). By the time opal_init() has completed, all
103 values should be substituted in that need substituting. Hence,
104 we take an extra parameter (is_setup) to know whether we should
105 do this futzing or not. */
106 if (is_setup) {
107 destdir = getenv("OPAL_DESTDIR");
108 if (NULL != destdir && strlen(destdir) > 0) {
109 destdir_offset = strlen(destdir);
110 }
111 }
112
113 len = strlen(input);
114 for (i = 0 ; i < len ; ++i) {
115 if ('$' == input[i] || '@' == input[i]) {
116 needs_expand = true;
117 break;
118 }
119 }
120
121 retval = strdup(input);
122 if (NULL == retval) return NULL;
123
124 if (needs_expand) {
125 bool changed = false;
126 char *start_pos, *end_pos, *tmp;
127
128 do {
129 changed = false;
130 EXPAND_STRING(prefix);
131 EXPAND_STRING(exec_prefix);
132 EXPAND_STRING(bindir);
133 EXPAND_STRING(sbindir);
134 EXPAND_STRING(libexecdir);
135 EXPAND_STRING(datarootdir);
136 EXPAND_STRING(datadir);
137 EXPAND_STRING(sysconfdir);
138 EXPAND_STRING(sharedstatedir);
139 EXPAND_STRING(localstatedir);
140 EXPAND_STRING(libdir);
141 EXPAND_STRING(includedir);
142 EXPAND_STRING(infodir);
143 EXPAND_STRING(mandir);
144 EXPAND_STRING2(opaldatadir, pkgdatadir);
145 EXPAND_STRING2(opallibdir, pkglibdir);
146 EXPAND_STRING2(opalincludedir, pkgincludedir);
147 } while (changed);
148 }
149
150 if (NULL != destdir) {
151 char *tmp = retval;
152 retval = opal_os_path(false, destdir, tmp, NULL);
153 free(tmp);
154 }
155
156 return retval;
157 }
158
159
160 char *
opal_install_dirs_expand(const char * input)161 opal_install_dirs_expand(const char* input)
162 {
163 /* We do NOT want OPAL_DESTDIR expansion in this case. */
164 return opal_install_dirs_expand_internal(input, false);
165 }
166
167
168 char *
opal_install_dirs_expand_setup(const char * input)169 opal_install_dirs_expand_setup(const char* input)
170 {
171 /* We DO want OPAL_DESTDIR expansion in this case. */
172 return opal_install_dirs_expand_internal(input, true);
173 }
174