[devel] ccache support in gcc-common
Alexander Bokovoy
=?iso-8859-1?q?a=2Ebokovoy_=CE=C1_sam-solutions=2Enet?=
Ср Сен 17 20:13:32 MSD 2003
Greetings!
Предлагаю следующее добавление в gcc_wrapper, которое позволит наиболее
элегантным путем (как мне кажется) интегрировать ccache в сборочные
системы. Дело в том, что в текущий момент времени у нас есть следующие
проблемы с интеграцией в BTE:
1. Мы используем альтернативы для подмены gcc/g++/cpp на ccache так, чтобы
пакеты, которые не умеют смотреть на переменные окружения (например, CC)
работали с ccache.
2. Мы вынуждены прикладывать небольшой патч на ccache, чтобы вычислять,
кого же вызывать для реального выполнения задания (gcc/g++/cpp).
Однако у нас в системе уже есть gcc-common, а в нем gcc_wrapper, который
выполняет вызов архитектурно-зависимого компилятора (i586-alt-linux).
Делает он следующее:
1. Вычисляет имя архитектурно-зависимого компилятора, по умолчанию считая,
что вызывают gcc (i586-alt-linux-gcc).
2. Если установлена переменная окружения GCC_VERSION, то добавляет к этому
имени указанную версию и %bindir.
3. Вызывает получившуюся программу, передавая ей те же параметры, что и
были получены самим gcc_wrapper.
Что при этом происходит, можно понять по strace:
$ strace -e trace=process gcc_wrapper -V 3.2 -v
execve("/usr/bin/gcc_wrapper", ["gcc_wrapper", "-V", "3.2", "-v"], [/* 49 vars */]) = 0
execve("/usr/bin/i586-alt-linux-gcc", ["i586-alt-linux-gcc", "-V", "3.2", "-v"], [/* 49 vars */]) = 0
Using builtin specs.
gcc driver version 2.96 20000731 (ALT Linux, build 2.96-alt3) executing
gcc version 3.2
_exit(0)
Поскольку ccache работает по похожему принципу, можно вместо запуска
вычисленной программы (%bindir/%targetplatform-<gcc>-$GCC_VERSION)
запускать ccache, подставляя ему в качестве имени программы
архитектурно-зависимое имя компилятора -- i586-alt-linux-gcc-$GCC_VERSION
Получается следующее:
$ GCC_USE_CCACHE=1 strace -e trace=process ./gcc_wrapper -V 3.2 -v
execve("./gcc_wrapper", ["./gcc_wrapper", "-V", "3.2", "-v"], [/* 50 vars */]) = 0
execve("/usr/bin/ccache", ["i586-alt-linux-gcc", "-V", "3.2", "-v"], [/* 50 vars */]) = 0
execve("/usr/bin/i586-alt-linux-gcc", ["/usr/bin/i586-alt-linux-gcc", "-V", "3.2", "-v"], [/* 50 vars */]) = 0
Using builtin specs.
gcc driver version 2.96 20000731 (ALT Linux, build 2.96-alt3) executing
gcc version 3.2
_exit(0)
То есть, мы производим прозрачный запуск ccache, который уже сам
расправляется с тем, кого же надо будет запустить, по переданному ему
имени программы (i586-alt-linux-gcc в данном случае). Механизм сработает,
поскольку архитектурно-зависимые компиляторы представляют собой нормальные
исполняемые файлы, а не символические ссылки, управляемые альтернативами.
Заметьте, что в указанном примере я специально использовал опцию -V у gcc
для показа возможности интеграции с gcc-драйвером по вызову компилятора,
отличного по версии от запускаемого. То есть, все возможности
оригинального gcc при этом сохранены, для него все прозрачно -- он даже не
будет знать, что запускается с кэшированием.
Что при этом мы получаем:
1. ccache не требует модификаций.
2. Не требуется модификация альтернатив для подстановки ccache перед gcc.
3. ccache интегрируется в любое окружение, не только в BTE -- достаточно
поставить пакет ccache и выставить переменную окружения GCC_USE_CCACHE.
4. Не возникает ограничений по использованию ccache вместе с distcc на
одной и той же платформе -- в новом ccache (2.2) используется специальный
механизм CCACHE_PREFIX для интеграции с distcc. Если бы мы использовали
этот же подход для интеграции с BTE, то мы бы лишились возможности легко
интегрироваться с distcc и фактически породили бы аналог gcc_wrapper,
запускаемый из ccache.
В чем мы себе отказываем:
А ни в чем :) Запуск компилятора с архитектурой, отличной от архитектуры
по умолчанию, по-прежнему возможен посредством опции -b <machine> в gcc.
Вот патч:
--- gcc_wrapper.c.orig 2002-11-28 14:44:31 +0200
+++ gcc_wrapper.c 2003-09-17 18:31:02 +0300
@@ -14,6 +14,7 @@
char *suffix = "", *name, *path;
const char *progname = strcmp (__progname, "gcc_wrapper") ? __progname : "gcc";
const char *version = getenv ("GCC_VERSION");
+ const char *use_ccache = getenv ("GCC_USE_CCACHE");
if (version)
{
@@ -29,7 +30,7 @@
if (asprintf (&name, "%s-%s%s", TARGET, progname, suffix) < 0)
error (EXIT_FAILURE, errno, "asprintf");
- if (asprintf (&path, "%s/%s", BINDIR, name) < 0)
+ if (asprintf (&path, "%s/%s", BINDIR, (use_ccache) ? "ccache" : name) < 0)
error (EXIT_FAILURE, errno, "asprintf");
argv[0] = name;
Что нужно кроме него?
1. Убрать поддержку __ccache_cc/__ccache_cxx из rpm-build, они больше не
нужны.
2. Добавить выставление GCC_USE_CCACHE=1 в обработку __ccache_dir в
rpm-build.
Все. После этого исчезнет необходимость существования пакета ccache-bte и
все будет делаться в рамках gcc-common/ccache (без патчей!)/rpm-build.
Для того, чтобы активировать поддержку ccache в RPM надо будет только в
~/.macros поставить:
%__ccache_dir ~/.ccache или любой другой путь
--
/ Alexander Bokovoy
---
"He was a modest, good-humored boy. It was Oxford that made him insufferable."
Подробная информация о списке рассылки Devel