Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 128810 | Differences between
and this patch

Collapse All | Expand All

(-)src/compiler-wrapper/compiler-wrapper.c.orig (-24 / +204 lines)
Lines 94-99 Link Here
94
#define MAXPATHLEN 1023
94
#define MAXPATHLEN 1023
95
#endif
95
#endif
96
96
97
#ifndef FALSE
98
#define FALSE 0
99
#endif
100
#ifndef TRUE
101
#define TRUE 1
102
#endif
103
97
typedef struct {
104
typedef struct {
98
	/* The CHOST being compiled for.  This is determined by $ABI (deprecated),
105
	/* The CHOST being compiled for.  This is determined by $ABI (deprecated),
99
	 * the prefix of the executable, the environment ($CHOST), or the default
106
	 * the prefix of the executable, the environment ($CHOST), or the default
Lines 136-154 Link Here
136
		"-m32", "-m64", "-mabi", NULL
143
		"-m32", "-m64", "-mabi", NULL
137
	};
144
	};
138
145
139
	retargv = argv;
140
141
	/* make sure user hasn't specified any ABI flags already ...
146
	/* make sure user hasn't specified any ABI flags already ...
142
	 * if they have, lets just get out of here */
147
	 * if they have, lets just get out of here */
143
	for (argc = 0; argv[argc]; ++argc)
148
	for (argc = 0; argv[argc]; ++argc)
144
		for (i = 0; abiFlags[i]; ++i)
149
		for (i = 0; abiFlags[i]; ++i)
145
			if (!strncmp(argv[argc], abiFlags[i], strlen(abiFlags[i])))
150
			if (!strncmp(argv[argc], abiFlags[i], strlen(abiFlags[i])))
146
				return retargv;
151
				return argv;
147
152
148
	/* Tokenize the flag list and put it into newflags array */
153
	/* Tokenize the flag list and put it into newflags array */
149
	flagsTokenized = strdup(newFlagsStr);
154
	flagsTokenized = strdup(newFlagsStr);
150
	if (flagsTokenized == NULL)
155
	if (flagsTokenized == NULL)
151
		return retargv;
156
		return argv;
152
	i = 0;
157
	i = 0;
153
	newFlags[i] = strtok_r(flagsTokenized, " \t\n", &state);
158
	newFlags[i] = strtok_r(flagsTokenized, " \t\n", &state);
154
	while (newFlags[i] != NULL && i < MAX_NEWFLAGS-1)
159
	while (newFlags[i] != NULL && i < MAX_NEWFLAGS-1)
Lines 156-161 Link Here
156
161
157
	/* allocate memory for our spiffy new argv */
162
	/* allocate memory for our spiffy new argv */
158
	retargv = (char**)calloc(argc + i + 1, sizeof(char*));
163
	retargv = (char**)calloc(argc + i + 1, sizeof(char*));
164
	if (retargv == NULL) {
165
		free(flagsTokenized);
166
		return argv;
167
	}
159
	/* start building retargv */
168
	/* start building retargv */
160
	retargv[0] = argv[0];
169
	retargv[0] = argv[0];
161
	/* insert the ABI flags first so cmdline always overrides ABI flags */
170
	/* insert the ABI flags first so cmdline always overrides ABI flags */
Lines 164-172 Link Here
164
	if (argc > 1)
173
	if (argc > 1)
165
		memcpy(retargv+1+i, argv+1, (argc-1) * sizeof(char*));
174
		memcpy(retargv+1+i, argv+1, (argc-1) * sizeof(char*));
166
175
176
	free(flagsTokenized);
177
178
	return retargv;
179
}
180
181
/** Prepend SPECS to the argv list */
182
static char **buildNewArgvSpecs(char **argv, const char *newSpecsStr) {
183
#define MAX_NEWSPECS 32
184
	char *newSpecs[MAX_NEWSPECS];
185
	char **retargv;
186
	unsigned int argc;
187
	size_t nspecs;
188
	char *state, *flagsTokenized;
189
	char *spec;
190
191
	for (argc = 0; argv[argc]; ++argc);
192
193
	/* Tokenize the flag list and put it into newflags array */
194
	flagsTokenized = strdup(newSpecsStr);
195
	if (flagsTokenized == NULL)
196
		return argv;
197
	nspecs = 0;
198
	for (spec = strtok_r(flagsTokenized, ":", &state);
199
		 spec != NULL && nspecs < MAX_NEWSPECS;
200
		 spec = strtok_r(NULL, ":", &state)) {
201
		newSpecs[nspecs] = (char *)malloc((strlen(spec)+8) * sizeof(char));
202
		if (newSpecs[nspecs] == NULL) {
203
			free(flagsTokenized);
204
			return argv;
205
		}
206
		snprintf(newSpecs[nspecs], strlen(spec)+8, "-specs=%s", spec);
207
		nspecs++;
208
	}
209
210
	/* allocate memory for our spiffy new argv */
211
	retargv = (char**)calloc(argc + nspecs + 1, sizeof(char*));
212
	if (retargv == NULL) {
213
		free(flagsTokenized);
214
		return argv;
215
	}
216
	/* start building retargv */
217
	retargv[0] = argv[0];
218
	/* insert the ABI flags first so cmdline always overrides ABI flags */
219
	memcpy(retargv+1, newSpecs, nspecs * sizeof(char*));
220
	/* copy over the old argv */
221
	if (argc > 1)
222
		memcpy(retargv+1+nspecs, argv+1, (argc-1) * sizeof(char*));
223
224
	free(flagsTokenized);
225
167
	return retargv;
226
	return retargv;
168
}
227
}
169
228
229
/** Add path to the environment variable envVar */
230
static int addPathToEnv(char *envVar, char *path) {
231
	char *envVal;
232
	char *newEnvVal;
233
234
	envVal = getenv(envVar);
235
	if (envVal == NULL) {
236
		newEnvVal=strdup(path);
237
		if (newEnvVal == NULL)
238
			return FALSE;
239
	} else {
240
		newEnvVal = (char *)malloc((strlen(envVal)+1+strlen(path)+1)*sizeof(char));
241
		if (newEnvVal == NULL)
242
			return FALSE;
243
		snprintf(newEnvVal, strlen(envVal)+1+strlen(path)+1, "%s:%s", envVal,path);
244
	}
245
	setenv(envVar,newEnvVal,TRUE);
246
	return TRUE;
247
}
248
249
static char **prependArgv(char **argv, char *bin) {
250
	int argc;
251
	char **newArgv;
252
	for (argc=0; argv[argc]; argc++);
253
	newArgv = (char**)calloc(argc + 2, sizeof(char*));
254
	if (newArgv == NULL)
255
		return argv;
256
	newArgv[0]=bin;
257
	memcpy(newArgv+1,argv,(argc + 1) * sizeof(char *));
258
	return newArgv;
259
}
260
261
/** Return TRUE iff word is in COMPILER_FEATURES and -word is not (last wins) */
262
static int inFeatures(char *word) {
263
	char *features, *feature;
264
	char *state, *featuresTokenised;
265
	int on;
266
267
	features = getenv("COMPILER_FEATURES");
268
	if (features==NULL)
269
		return FALSE;
270
	featuresTokenised = strdup(features);
271
	if (featuresTokenised == NULL)
272
		return FALSE;
273
	on = FALSE;
274
	for (feature = strtok_r(featuresTokenised, " \t\n", &state);
275
		 feature != NULL;
276
		 feature = strtok_r(NULL, " \t\n", &state)) {
277
		if (strcmp(feature,word)==0) {
278
			on = TRUE;
279
		} else if (word[0]=='-' && strcmp(feature,word+1)==0) {
280
			on = FALSE;
281
		}
282
	}
283
	return on;
284
}
285
286
/** Return TRUE iff distcc is wanted */
287
static int distccRequired(void) {
288
	return inFeatures("distcc");
289
}
290
291
/** Return TRUE iff distcc is wanted */
292
static int ccacheRequired(void) {
293
	return inFeatures("ccache");
294
}
295
296
/** Set environment variable envVar to environment variable envDir
297
 * suffixed with , provided envVar is empty or not defined.
298
 * Returns TRUE if the envVar is already set, or if it is
299
 * successfully set. */
300
static int appendEnv(char *envVar, char *envDir, char *suffix) {
301
	char *envVarVal;
302
	char *envDirVal;
303
	envVarVal = getenv (envVar);
304
	if (envVarVal == NULL || strlen(envVarVal)==0) {
305
		if (envDir == NULL) {
306
			setenv(envVar,suffix,TRUE);
307
		} else {
308
			envDirVal = getenv(envDir);
309
			if (envDirVal == NULL)
310
				return FALSE;
311
			envVarVal = (char *)malloc((strlen(envDirVal)+strlen(suffix)+1)*sizeof(char));
312
			if (envVarVal == NULL)
313
				return FALSE;
314
			if (snprintf(envVarVal, strlen(envDirVal)+strlen(suffix)+1,"%s%s",envDirVal,suffix) < 0)
315
				return FALSE;
316
			setenv(envVar,envVarVal,TRUE);
317
		}
318
	}
319
	return TRUE;
320
}
321
170
/** Set the ctarget and profile */
322
/** Set the ctarget and profile */
171
static void setCtargetAndProfile(WrapperData *data) {
323
static void setCtargetAndProfile(WrapperData *data) {
172
	char tmp[MAXPATHLEN + 1];
324
	char tmp[MAXPATHLEN + 1];
Lines 265-293 Link Here
265
}
417
}
266
418
267
int main(int argc, char *argv[]) {
419
int main(int argc, char *argv[]) {
268
	WrapperData *data;
420
	WrapperData data;
269
	char *extraCflags = NULL;
421
	char *extraCflags = NULL;
422
	char *gcc_specs;
270
	
423
	
271
	data = (WrapperData *)alloca(sizeof(WrapperData));
272
	if(data == NULL)
273
		die("Memory allocation failure.");
274
275
	/* Load the config file */
424
	/* Load the config file */
276
	data->selectionConf = loadSelectionConf(CONFIGURATION_DIR, 1);
425
	data.selectionConf = loadSelectionConf(CONFIGURATION_DIR, 1);
277
	if(data->selectionConf == NULL)
426
	if(data.selectionConf == NULL)
278
		die("Memory allocation failure.");
427
		die("Memory allocation failure.");
279
428
280
	/* The argv to pass to the forked process.  Defaults to be the same */
429
	/* The argv to pass to the forked process.  Defaults to be the same */
281
	data->argv = argv;
430
	data.argv = argv;
282
431
283
	/* Figure out out CTARGET and our Profile */
432
	/* Figure out out CTARGET and our Profile */
284
	setCtargetAndProfile(data);
433
	setCtargetAndProfile(&data);
285
434
286
	/* Determine what binary we will be executing */
435
	/* Determine what binary we will be executing */
287
	setExecBinary(data);
436
	setExecBinary(&data);
288
437
289
	/* Do we need to set any additional CFLAGS? */
438
	/* Do we need to set any additional CFLAGS? */
290
	if(data->selectionConf->useABI && getenv("ABI")) {
439
	if(data.selectionConf->useABI && getenv("ABI")) {
291
		/* This functionality is deprecated and subject to be removed
440
		/* This functionality is deprecated and subject to be removed
292
		 * once all profiles in portage nolonger depend on it.
441
		 * once all profiles in portage nolonger depend on it.
293
		 */
442
		 */
Lines 297-325 Link Here
297
		if (getenv(envvar))
446
		if (getenv(envvar))
298
			extraCflags = getenv(envvar);
447
			extraCflags = getenv(envvar);
299
	} else {
448
	} else {
300
		extraCflags = ((Profile *)hashGet(data->selectionConf->selectionHash, data->ctarget))->cflags;
449
		extraCflags = ((Profile *)hashGet(data.selectionConf->selectionHash, data.ctarget))->cflags;
301
	}
450
	}
302
451
303
	if(extraCflags) {
452
	if(extraCflags) {
304
		data->argv = buildNewArgv(data->argv, extraCflags);
453
		data.argv = buildNewArgv(data.argv, extraCflags);
305
		if(data->argv == NULL)
454
		if(data.argv == NULL)
306
			die("Memory allocation failure.");
455
			die("Memory allocation failure.");
307
	}
456
	}
308
457
309
	/* Select the appropriate GCC specs file */
458
	/* Convert env specs or config specs into arguments
310
	if(data->profile->specs && getenv("GCC_SPECS") == NULL)
459
	 * Env GCC_SPECS is honoured for native compiler only
311
		setenv("GCC_SPECS", data->profile->specs, 1);
460
	 */
461
	gcc_specs = getenv("GCC_SPECS");
462
	if (gcc_specs &&
463
		strcmp(data.ctarget, data.selectionConf->defaultCtarget) == 0) {
464
		data.argv = buildNewArgvSpecs(data.argv, gcc_specs);
465
	} else if (data.profile->specs) {
466
		data.argv = buildNewArgvSpecs(data.argv, data.profile->specs);
467
	}
468
	unsetenv("GCC_SPECS");
312
469
313
	/* Set argv[0] to the correct binary (the full path
470
	/* Set argv[0] to the correct binary (the full path
314
	 * of the binary we are executing), else gcc can't
471
	 * of the binary we are executing), else gcc can't
315
	 * find internal headers
472
	 * find internal headers
316
	 * http://bugs.gentoo.org/show_bug.cgi?id=8132
473
	 * http://bugs.gentoo.org/show_bug.cgi?id=8132
317
	 */
474
	 */
318
	data->argv[0] = data->execBinary;
475
	data.argv[0] = data.execBinary;
476
477
	/* Prepend distcc, if enabled.
478
	 * Set DISTCC_DIR to PORTAGE_TMPDIR/.distcc if not already set
479
	 * Append DISTCC_DIR to SANDBOX_WRITE
480
	 * Shuffle argv and set argv[0] to /usr/bin/distcc
481
	 */
482
	if (distccRequired() &&
483
		appendEnv("DISTCC_DIR", "PORTAGE_TMPDIR", "/.distcc") &&
484
		addPathToEnv("SANDBOX_WRITE",getenv("DISTCC_DIR"))) {
485
		data.argv = prependArgv(data.argv, "/usr/bin/distcc");
486
	}
487
488
	/* Prepend ccache, if enabled.
489
	 * Set CCACHE_DIR to /var/tmp/ccache if not already set
490
	 * Append CCACHE_DIR to SANDBOX_WRITE, SANDBOX_READ
491
	 * Shuffle argv and set argv[0] to /usr/bin/ccache
492
	 */
493
	if (ccacheRequired() &&
494
		appendEnv("CCACHE_DIR", NULL, "/var/tmp/ccache") &&
495
		addPathToEnv("SANDBOX_READ",getenv("CCACHE_DIR")) &&
496
		addPathToEnv("SANDBOX_WRITE",getenv("CCACHE_DIR"))) {
497
		data.argv = prependArgv(data.argv, "/usr/bin/ccache");
498
	}
319
499
320
	/* Ok, lets exec it. */
500
	/* Ok, lets exec it. */
321
	if (execv(data->execBinary, data->argv) < 0)
501
	if (execv(data.argv[0], data.argv) < 0)
322
		die("Could not run/locate \"%s\"", data->execBinary);
502
		die("Could not run/locate \"%s\"", data.argv[0]);
323
503
324
	return 0;
504
	return 0;
325
}
505
}

Return to bug 128810