summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schlemmer <azarah@gentoo.org>2003-04-12 18:44:22 +0000
committerMartin Schlemmer <azarah@gentoo.org>2003-04-12 18:44:22 +0000
commit74a193d17b51172b9702d27c5b51b25fa6a82df6 (patch)
tree9c8698e26b432e52a5c92654b83b4c976217c98b
parentoptimizations; use new wrapper (diff)
downloadgcc-config-74a193d17b51172b9702d27c5b51b25fa6a82df6.tar.gz
gcc-config-74a193d17b51172b9702d27c5b51b25fa6a82df6.tar.bz2
gcc-config-74a193d17b51172b9702d27c5b51b25fa6a82df6.zip
New version
- lots of speed improvements to wrapper - short options - select profile by number
-rwxr-xr-xgcc-config68
-rw-r--r--wrapper.c115
2 files changed, 154 insertions, 29 deletions
diff --git a/gcc-config b/gcc-config
index 89b5e31..c92dd04 100755
--- a/gcc-config
+++ b/gcc-config
@@ -2,7 +2,7 @@
# Copyright 1999-2003 Gentoo Foundation
# Distributed under the terms of the GNU General Public License
# Author: Martin Schlemmer <azarah@gentoo.org>
-# $Header: gentoo-x86/sys-devel/gcc-config/files/gcc-config-1.3.2,v 1.1 2003/04/08 12:53:38 azarah Exp $
+# $Header: gentoo-x86/sys-devel/gcc-config/files/gcc-config-1.3.3,v 1.1 2003/04/12 18:44:22 azarah Exp $
source /etc/init.d/functions.sh || {
@@ -17,26 +17,34 @@ Change the current cc/gcc profile, or give info about profiles.
Options:
- --use-old Use the old profile if one was selected.
+ -O, --use-old
+ Use the old profile if one was selected.
- --use-portage-chost Only set to given profile if its CHOST is the same
+ -P, --use-portage-chost
+ Only set to given profile if its CHOST is the same
as that set for portage in /etc/make.conf (or one of
other portage config files...).
- --get-current-profile Print current used gcc profile.
+ -c, --get-current-profile
+ Print current used gcc profile.
- --list-profiles Print a list of available profiles.
+ -l, --list-profiles
+ Print a list of available profiles.
- --print-environ Print environment that can be used to setup things
+ -E, --print-environ
+ Print environment that can be used to setup things
for current gcc profile, or specified one ...
- --get-bin-path Print path where binaries of given/current profile
+ -B, --get-bin-path
+ Print path where binaries of given/current profile
are located.
- --get-lib-path Print path where libraries of given/current profile
+ -L, --get-lib-path
+ Print path where libraries of given/current profile
are located.
- --get-stdcxx-incdir Print path to g++ include files of given/current
+ -X, --get-stdcxx-incdir
+ Print path to g++ include files of given/current
profile.
The profile name is in the form of:
@@ -252,6 +260,8 @@ get_current_profile() {
}
list_profiles() {
+ i=1
+
if [ ! -f /etc/env.d/gcc/config ]
then
eerror "$0: No gcc profile is active!"
@@ -262,7 +272,8 @@ list_profiles() {
do
if [ -f "${x}" -a "${x}" != "/etc/env.d/gcc/config" ]
then
- echo "${x##*/}"
+ echo "[${i}] ${x##*/}"
+ i=$((i + 1))
fi
done
}
@@ -317,65 +328,82 @@ for x in $*
do
case "${x}" in
# Only use specified compiler if one is not already selected.
- --use-old)
+ -O|--use-old)
if get_current_profile &> /dev/null
then
CC_COMP="$(get_current_profile)"
fi
;;
- --use-portage-chost)
+ -P|--use-portage-chost)
CHECK_CHOST="yes"
;;
- --get-current-profile)
+ -c|--get-current-profile)
if [ "${NEED_ACTION}" = "yes" ]
then
NEED_ACTION="no"
DOIT="get_current_profile"
fi
;;
- --list-profiles)
+ -l|--list-profiles)
if [ "${NEED_ACTION}" = "yes" ]
then
NEED_ACTION="no"
DOIT="list_profiles"
fi
;;
- --print-environ)
+ -E|--print-environ)
if [ "${NEED_ACTION}" = "yes" ]
then
NEED_ACTION="no"
DOIT="print_environ"
fi
;;
- --get-bin-path)
+ -B|--get-bin-path)
if [ "${NEED_ACTION}" = "yes" ]
then
NEED_ACTION="no"
DOIT="get_bin_path"
fi
;;
- --get-lib-path)
+ -L|--get-lib-path)
if [ "${NEED_ACTION}" = "yes" ]
then
NEED_ACTION="no"
DOIT="get_lib_path"
fi
;;
- --get-stdcxx-incdir)
+ -X|--get-stdcxx-incdir)
if [ "${NEED_ACTION}" = "yes" ]
then
NEED_ACTION="no"
DOIT="get_stdcxx_incdir"
fi
;;
- --*)
+ -*)
eerror "$0: Invalid switch! Run $0 without parameters for help."
exit 1
;;
*)
if [ -z "${CC_COMP}" ]
then
- CC_COMP="${x}"
+ if [ -n "`echo ${x} | gawk '/^[[:digit:]]*$/ { print }'`" ]
+ then
+ i=1
+ for y in /etc/env.d/gcc/*
+ do
+ [ "${y}" = "/etc/env.d/gcc/config" ] && continue
+
+ if [ -f "${y}" -a "${x}" -eq "${i}" ]
+ then
+ CC_COMP="${y##*/}"
+ break
+ else
+ i=$((i + 1))
+ fi
+ done
+ else
+ CC_COMP="${x}"
+ fi
fi
;;
esac
diff --git a/wrapper.c b/wrapper.c
index 2fec1e3..0ad8c58 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -2,7 +2,7 @@
* Copyright 1999-2003 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
* Author: Martin Schlemmer <azarah@gentoo.org>
- * $Header: gentoo-x86/sys-devel/gcc-config/files/wrapper-1.4.c,v 1.1 2003/02/23 16:20:10 azarah Exp $
+ * $Header: gentoo-x86/sys-devel/gcc-config/files/wrapper-1.4.1.c,v 1.1 2003/04/12 18:44:22 azarah Exp $
*/
#define _REENTRANT
@@ -20,6 +20,11 @@
#include <stdarg.h>
#include <errno.h>
+//#define DEBUG
+
+#define GCC_CONFIG "/usr/bin/gcc-config"
+#define ENVD_FILE "/etc/env.d/05gcc"
+
struct wrapper_data {
char name[MAXPATHLEN + 1];
char fullname[MAXPATHLEN + 1];
@@ -44,9 +49,10 @@ static void wrapper_exit(char *msg, ...)
exit(1);
}
-/* find_bin checks in path for the file we are seeking
- it returns 1 if found (with data->bin setup), 0 if not
- and negative on error */
+/* check_for_target checks in path for the file we are seeking
+ * it returns 1 if found (with data->bin setup), 0 if not and
+ * negative on error
+ */
static int check_for_target(char *path, struct wrapper_data *data)
{
struct stat sbuf;
@@ -57,13 +63,15 @@ static int check_for_target(char *path, struct wrapper_data *data)
snprintf(str, len, "%s/%s", path, data->name);
/* Stat possible file to check that
- 1) it exist and is a regular file, and
- 2) it is not the wrapper itself, and
- 3) it is in a /gcc-bin/ directory tree */
+ * 1) it exist and is a regular file, and
+ * 2) it is not the wrapper itself, and
+ * 3) it is in a /gcc-bin/ directory tree
+ */
result = stat(str, &sbuf);
if ((0 == result) && (sbuf.st_mode & S_IFREG) &&
(0 != strcmp(str, data->fullname)) &&
(0 != strstr(str, "/gcc-bin/"))) {
+
strncpy(data->bin, str, MAXPATHLEN);
data->bin[MAXPATHLEN] = 0;
result = 1;
@@ -91,6 +99,7 @@ static int find_target_in_path(struct wrapper_data *data)
* able to build something with a non default gcc by just tweaking
* the PATH ... */
while ((NULL != token) && (strlen(token) > 0)) {
+
if (check_for_target(token, data))
return 1;
@@ -100,21 +109,105 @@ static int find_target_in_path(struct wrapper_data *data)
return 0;
}
+/* find_target_in_envd parses /etc/env.d/05gcc, and tries to
+ * extract PATH, which is set to the current profile's bin
+ * directory ...
+ */
+static int find_target_in_envd(struct wrapper_data *data)
+{
+ FILE *envfile = NULL;
+ char *token = NULL, *str = data->tmp, *state;
+
+ if (NULL == data->path) return 0;
+
+ envfile = fopen(ENVD_FILE, "r");
+ if (NULL == envfile)
+ return 0;
+
+ while (0 != fgets(str, MAXPATHLEN, envfile)) {
+
+ /* Keep reading ENVD_FILE until we get a line that
+ * starts with 'PATH='
+ */
+ if (((str) && (strlen(str) > strlen("PATH=")) &&
+ 0 == strncmp("PATH=", str, strlen("PATH=")))) {
+
+ token = strtok_r(str, "=", &state);
+ if ((NULL != token) && (strlen(token) > 0))
+ /* The second token should be the value of PATH .. */
+ token = strtok_r(NULL, "=", &state);
+ else {
+ fclose(envfile);
+ return 0;
+ }
+
+ if ((NULL != token) && (strlen(token) > 0)) {
+
+ str = token;
+#ifdef DEBUG
+ printf("* token = %s\n", token);
+#endif
+ /* A bash variable may be unquoted, quoted with " or
+ * quoted with ', so extract the value without those ..
+ */
+ token = strsep(&str, "\n\"\'");
+#ifdef DEBUG
+ printf("* token = %s\n", token);
+#endif
+
+ while (NULL != token) {
+
+ if (check_for_target(token, data)) {
+
+ fclose(envfile);
+ return 1;
+ }
+
+ token = strsep(&str, "\n\"\'");
+#ifdef DEBUG
+ printf("* token = %s\n", token);
+#endif
+ }
+ }
+
+ }
+ str = data->tmp;
+ }
+
+ fclose(envfile);
+
+ return 0;
+}
+
static void find_wrapper_target(struct wrapper_data *data)
{
FILE *inpipe = NULL;
char *str = data->tmp;
+#ifdef DEBUG
+ printf("* calling find_target_in_path\n");
+#endif
if (find_target_in_path(data))
return;
+#ifdef DEBUG
+ printf("* calling find_target_in_envd\n");
+#endif
+ if (find_target_in_envd(data))
+ return;
+
+#ifdef DEBUG
+ printf("* calling find_wrapper_target\n");
+#endif
+
/* Only our wrapper is in PATH, so
get the CC path using gcc-config and
execute the real binary in there... */
- inpipe = popen("/usr/bin/gcc-config --get-bin-path", "r");
+ inpipe = popen(GCC_CONFIG " --get-bin-path", "r");
if (NULL == inpipe) {
+
wrapper_exit(
- "Could not open pipe for /usr/bin/gcc-config: %s\n",
+ "Could not open pipe for GCC_CONFIG: %s\n",
wrapper_strerror(errno, data));
}
@@ -219,6 +312,10 @@ int main(int argc, char **argv)
* headers, etc (bug #8132). */
argv[0] = data->bin;
+#ifdef DEBUG
+ printf("exec %s\n", data->bin);
+#endif
+
/* Ok, do it ... */
if (execv(data->bin, argv) < 0)
wrapper_exit("Could not run/locate \"%s\"\n", data->name);