Bug 40628

Summary: Enable -grecord-gcc-switches in clang by default
Product: Sisyphus Reporter: Vitaly Chikunov <vt>
Component: llvm12.0Assignee: Konstantin A Lepikhov (L.A. Kostis) <lakostis>
Status: CLOSED FIXED QA Contact: qa-sisyphus
Severity: normal    
Priority: P5 CC: lakostis, ldv
Version: unstable   
Hardware: x86   
OS: Linux   
See Also: https://bugzilla.altlinux.org/show_bug.cgi?id=34162

Description Vitaly Chikunov 2021-08-02 04:01:07 MSK
В GCC флаг -grecord-gcc-switches включен по умолчанию, gcc(1):

   -grecord-gcc-switches
       This switch causes the command-line options used to invoke
       the compiler that may affect code generation to be appended to
       the DW_AT_producer attribute in DWARF debugging information.
       The options are concatenated with spaces separating them
       from each other and from the compiler version.  It is enabled
       by default.

Если включить его по умолчанию в clang, то это будет полезно для анализа флагов сборки у собранных бинарников, см. пример #34162, и не добавлять его в optflags (а значит он и не потеряется по какой-либо ошибке).
Comment 1 Arseny Maslennikov 2021-08-10 23:04:44 MSK
Это нужно для сборки пакетов или для пользователей, которые просто зачем-то запускают clang на альте?

Так-то мысль вполне интересная и достойна того, чтобы её тем или иным способом сделать.
Comment 2 Dmitry V. Levin 2021-08-11 00:54:15 MSK
(In reply to Arseny Maslennikov from comment #1)
> Это нужно для сборки пакетов или для пользователей, которые просто зачем-то
> запускают clang на альте?

И для тех, и для других, и для паритета с gcc.
Comment 3 Vitaly Chikunov 2021-08-12 18:41:26 MSK
Думаю, можно было собрать уже в (следующей) этой сборке, ведь там однострочник.

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index e13302528cbd..04ab829d0333 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6581,7 +6581,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   // By default, -gno-record-gcc-switches is set on and no recording.
   auto GRecordSwitches =
       Args.hasFlag(options::OPT_grecord_command_line,
-                   options::OPT_gno_record_command_line, false);
+                   options::OPT_gno_record_command_line, true);
   auto FRecordSwitches =
       Args.hasFlag(options::OPT_frecord_command_line,
                    options::OPT_fno_record_command_line, false);
Comment 4 Arseny Maslennikov 2021-08-13 16:00:09 MSK
(In reply to Vitaly Chikunov from comment #3)
> Думаю, можно было собрать уже в (следующей) этой сборке, ведь там
> однострочник.

Как минимум надо ещё запатчить документацию.

> diff --git a/clang/lib/Driver/ToolChains/Clang.cpp
> b/clang/lib/Driver/ToolChains/Clang.cpp
> index e13302528cbd..04ab829d0333 100644
> --- a/clang/lib/Driver/ToolChains/Clang.cpp
> +++ b/clang/lib/Driver/ToolChains/Clang.cpp

Если влияет только на driver — программу clang, то ещё ладно. Трогать умолчания где-то внутри libclang — только искать неприятностей.

> @@ -6581,7 +6581,7 @@ void Clang::ConstructJob(Compilation &C, const
> JobAction &JA,
>    // By default, -gno-record-gcc-switches is set on and no recording.
>    auto GRecordSwitches =
>        Args.hasFlag(options::OPT_grecord_command_line,
> -                   options::OPT_gno_record_command_line, false);
> +                   options::OPT_gno_record_command_line, true);
>    auto FRecordSwitches =
>        Args.hasFlag(options::OPT_frecord_command_line,
>                     options::OPT_fno_record_command_line, false);
Comment 5 Arseny Maslennikov 2021-08-13 16:08:43 MSK
% cat a01.c
#include <stdio.h>

int main() {
    char r = '\0';
    char g = '\1';
    printf("%c %c\n", r, g);
    return 0;
}

% clang -O0 -g -grecord-command-line -c -o a01-grcl.c.o a01.c
% clang -O0 -g -c -o a01.c.o a01.c                          
% readelf --debug-dump=info a01-grcl.c.o > a01-grcl.c.o.readelf-debug
% readelf --debug-dump=info a01.c.o > a01.c.o.readelf-debug 
% diff -u a01.c.o.readelf-debug a01-grcl.c.o.readelf-debug           
--- a01.c.o.readelf-debug	2021-08-13 16:03:03.361372750 +0300
+++ a01-grcl.c.o.readelf-debug	2021-08-13 16:02:57.101331722 +0300
@@ -6,41 +6,41 @@
    Abbrev Offset: 0x0
    Pointer Size:  8
  <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
-    <c>   DW_AT_producer    : (indirect string, offset: 0x0): Debian clang version 11.0.1-2
+    <c>   DW_AT_producer    : (indirect string, offset: 0x0): Debian clang version 11.0.1-2 /usr/lib/llvm-11/bin/clang -O0 -g -grecord-command-line -c -o a01-grcl.c.o a01.c
     <10>   DW_AT_language    : 12	(ANSI C99)

...и ещё пачка отличающихся смещений indirect strings. Вроде ничего особенного.

Решил навести справки, что по этому поводу думает апстрим:
https://bugs.llvm.org/show_bug.cgi?id=32226
Ничего особенного не думает, но слегка склонился в сторону "не включать по умолчанию". Думаю, мы имеем право — тоже слегка — придержаться другого мнения.
Comment 6 Dmitry V. Levin 2021-09-10 02:16:19 MSK
(In reply to Arseny Maslennikov from comment #4)
> (In reply to Vitaly Chikunov from comment #3)
> > Думаю, можно было собрать уже в (следующей) этой сборке, ведь там
> > однострочник.
> 
> Как минимум надо ещё запатчить документацию.

Двустрочник? :)

Давайте уже сделаем!
Comment 7 Arseny Maslennikov 2021-09-11 12:53:57 MSK
(In reply to Dmitry V. Levin from comment #6)
> (In reply to Arseny Maslennikov from comment #4)
> > (In reply to Vitaly Chikunov from comment #3)
> > > Думаю, можно было собрать уже в (следующей) этой сборке, ведь там
> > > однострочник.
> > 
> > Как минимум надо ещё запатчить документацию.
> 
> Двустрочник? :)

Нет, оказалось больше:

--- a/tools/clang/docs/ClangCommandLineReference.rst	2021-06-28 16:23:38.000000000 +0000
+++ b/tools/clang/docs/ClangCommandLineReference.rst	2021-09-11 09:04:24.160000000 +0000
@@ -3521,6 +3521,19 @@
<...>
> 
> Давайте уже сделаем!

Да, давайте. Готовлю srpm с этим и другими изменениями.
Мне пришлось на 4 дня выпасть из рабочего процесса, так бы уже раньше было.
Comment 8 Arseny Maslennikov 2021-09-13 19:46:20 MSK
#200 llvm12.0 12.0.1-alt1 -> 12.0.1-alt2
 Sun Sep 05 2021 Arseny Maslennikov <arseny@altlinux> 12.0.1-alt2
 - Marked the package as built by ALT Linux Team (-DPACKAGE_VENDOR) so it's
   easier to distinguish from custom builds.
 - If compiled with gcc, we now pass -ffat-lto-objects to it.
 - Enabled -grecord-command-line by default (closes: bug 40628).
   Code generation is unaffected.

TODO: отразить на altlinux.org/LLVM.
Comment 9 Vitaly Chikunov 2021-09-13 19:50:49 MSK
Спасибо!

ps.
> Готовлю srpm с этим и другими изменениями.

А в чем прикол собирать из srpm?
Comment 10 Arseny Maslennikov 2021-09-13 23:07:51 MSK
(In reply to Vitaly Chikunov from comment #9)
> Спасибо!
> 
> ps.
> > Готовлю srpm с этим и другими изменениями.
> 
> А в чём прикол собирать из srpm?

Излагаю ниже одну причину; кроме неё, больше ни в чём, сам страдаю.

llvm project выпускает релизные тарболлы[1], которые — не совсем результат работы git-archive(1).
[1] https://github.com/llvm/llvm-project/releases/tag/llvmorg-12.0.1
По в основном историческим причинам спек, как можно убедиться из директив в нём и его секции %prep, рассчитан на сборку из них. Если зайти на gitery/srpms/l/llvm12.0.git, полученный при помощи gear-srpmimport, там в .gear/rules будет:

copy: *.patch
tar.xz: clang name=clang-12.0.1.src
tar.xz: clang-tools-extra name=clang-tools-extra-12.0.1.src
tar.xz: compiler-rt name=compiler-rt-12.0.1.src
tar.xz: lld name=lld-12.0.1.src
tar.xz: lldb name=lldb-12.0.1.src
tar.xz: llvm name=llvm-12.0.1.src

Ну и т. д. по мере роста числа компонентов (а их регулярно становится больше).
Это удобно, чтобы ползать по исходникам, патчить их и держать патчи в git-графе (но полученные таким образом патчи не наложатся в rpmbuild).
Это жутко неудобно, если из таких gear-правил собирать: снова пережимать их в tar.xz.
Да и зачем, если можно просто выдать программе rpmbuild апстримный тарболл? Собирая из srpm, я так и делаю. Более того, при обработке коммита вроде 12.0.0 -> 12.0.1 с гигантским дифференциалом* начинает тормозить уже сам git.

---
Как это сопровождать при помощи gear? Держать в gear-репе спек, патчи, тарболлы.

Инструментарию gear не хватает фичи unroll-sources, которая может превратить M апстримных тарболлов + N патчей в ветку с M коммитов, добавляющих содержимое этих тарболлов, и ещё N коммитов, патчащих это содержимое. Тогда workflow правки исходников сведётся к:
* gear-unroll-sources;
* совершение правки, коммит;
* gear-rollback-sources — checkout на HEAD момента совершения действия unroll-sources и обратная процедура, которая изменит состав хранимых патчей и, возможно, занесёт его в индекс, подобно gear-store-tags(1).

workflow обновления же сведётся к замене тарболла.

В правилах стоит сделать возможность задать и сам тарболл в виде blob в git-репе, который можно просто copy и использовать как RPM Source, и сведения о том, как его распаковать для деликатной работы с самими исходниками. (Не надо парсить секцию %prep, ничего хорошего из этого не выйдет)

Мне доподлинно известно, что некоторые коллеги либо используют самописное подобие такого инструмента, либо хотели бы использовать.

---
*Дифференциал коммита — совокупность его метаданных и диффа его дерева с деревом его предка. Её обычно показывает git show. Термин введён с целью отличить дифференциал коммита от самого коммита, который телесно представляет собой не дифф, а дерево.
Comment 11 Vitaly Chikunov 2021-09-15 01:07:42 MSK
(Ответ для Arseny Maslennikov на комментарий #10)

Спасибо за подробное объяснение!