Почему clang все еще нуждается в libgcc.a для компиляции моего кода?
int main(int argc, char **argv)
{
return 0;
}
Я перекрестно компилирую (host = linux x86_64, target = linux aarch64)
/path/to/clang --target=aarch64-Linux-gnu -v main.cpp -o main -fuse-Ld=lld -L./libs -Lc -Lc_nonshared -Xlinker -Map=a.map
В папке -L./libs я поставил все зависимости из цели. Когда я исключаю libgcc.a, возникает ошибка компоновщика
ld.lld: error: unable to find library -Lgcc
Я добавил параметр -Map, чтобы получить информацию о связанных статических библиотеках. В файле карты я не вижу ссылок на libgcc.a... но я сражаюсь за чтение файла карты. Существует много строк с <internal>
. Не уверен, что это такое. См.
Вопросы
- Почему libgcc.a все еще требуется для такой простой программы? Я читал 1 и 2, и я посмотрел на 3.
- Есть ли
- (a) линкер требует, чтобы libgcc выполнял свою собственную работу по связыванию или
- (b) использует ли компоновщик libgcc, потому что для моего кода требуется что-то, что предусмотрено libgcc
- Я думаю, что это (б), но я просто хочу быть уверенным.
карта
VMA LMA Size Align Out In Symbol
10270 10270 1b 1 .interp
10270 10270 1b 1 <internal>:(.interp)
10290 10290 a8 8 .dynsym
10290 10290 a8 8 <internal>:(.dynsym)
10338 10338 e 2 .gnu.version
10338 10338 e 2 <internal>:(.gnu.version)
10348 10348 20 4 .gnu.version_r
10348 10348 20 4 <internal>:(.gnu.version_r)
10368 10368 1c 8 .gnu.hash
10368 10368 1c 8 <internal>:(.gnu.hash)
10384 10384 87 1 .dynstr
10384 10384 87 1 <internal>:(.dynstr)
10410 10410 18 8 .rela.dyn
10410 10410 18 8 <internal>:(.rela.dyn)
10428 10428 48 8 .rela.plt
10428 10428 48 8 <internal>:(.rela.plt)
10470 10470 20 4 .note.ABI-tag
10470 10470 20 4 crt1.o:(.note.ABI-tag)
10470 10470 0 1 $d
10490 10490 4 4 .rodata
10490 10490 4 4 <internal>:(.rodata)
10494 10494 c 4 .eh_frame_hdr
10494 10494 c 4 <internal>:(.eh_frame_hdr)
104a0 104a0 4 4 .eh_frame
20000 20000 210 8 .text
20000 20000 48 8 crt1.o:(.text)
20000 20000 0 1 $x
20000 20000 0 1 _start
2002c 2002c 0 1 $d
20048 20048 14 4 crti.o:(.text)
20048 20048 0 1 $x
20048 20048 14 1 call_weak_fn
20060 20060 e0 8 crtbegin.o:(.text)
20060 20060 0 1 $x
20060 20060 0 1 deregister_tm_clones
20090 20090 0 1 $d
20098 20098 0 1 $x
20098 20098 0 1 register_tm_clones
200d0 200d0 0 1 $d
200d8 200d8 0 1 $x
200d8 200d8 0 1 __do_global_dtors_aux
20108 20108 0 1 frame_dummy
20138 20138 0 1 $d
20140 20140 54 4 /tmp/main-762849.o:(.text)
20140 20140 0 1 $x.0
20140 20140 10 1 do_math(int*)
20150 20150 44 1 main
20194 20194 7c 4 ./libs/libc_nonshared.a(elf-init.oS):(.text)
20194 20194 0 1 $x
20194 20194 78 1 __libc_csu_init
2020c 2020c 4 1 __libc_csu_fini
20210 20210 0 1 crtend.o:(.text)
20210 20210 0 1 crtn.o:(.text)
20210 20210 14 4 .init
20210 20210 c 4 crti.o:(.init)
20210 20210 0 1 $x
20210 20210 0 1 _init
2021c 2021c 8 1 crtn.o:(.init)
2021c 2021c 0 1 $x
20224 20224 10 4 .fini
20224 20224 8 4 crti.o:(.fini)
20224 20224 0 1 $x
20224 20224 0 1 _fini
2022c 2022c 8 1 crtn.o:(.fini)
2022c 2022c 0 1 $x
20240 20240 50 16 .plt
20240 20240 50 16 <internal>:(.plt)
30000 30000 10 8 .data
30000 30000 4 1 crt1.o:(.data)
30000 30000 0 1 data_start
30000 30000 0 1 __data_start
30004 30004 0 1 crti.o:(.data)
30008 30008 8 8 crtbegin.o:(.data)
30008 30008 0 1 $d
30008 30008 0 1 __dso_handle
30010 30010 0 1 ./libs/libc_nonshared.a(elf-init.oS):(.data)
30010 30010 0 1 crtend.o:(.data)
30010 30010 0 1 crtn.o:(.data)
30010 30010 0 8 .tm_clone_table
30010 30010 0 8 crtbegin.o:(.tm_clone_table)
30010 30010 0 1 __TMC_LIST__
30010 30010 0 8 crtend.o:(.tm_clone_table)
30010 30010 0 1 __TMC_END__
30010 30010 30 8 .got.plt
30010 30010 30 8 <internal>:(.got.plt)
40000 40000 8 8 .jcr
40000 40000 0 8 crtbegin.o:(.jcr)
40000 40000 0 1 __JCR_LIST__
40000 40000 8 8 crtend.o:(.jcr)
40000 40000 0 1 $d
40000 40000 0 1 __JCR_END__
40008 40008 8 8 .fini_array
40008 40008 8 8 crtbegin.o:(.fini_array)
40008 40008 0 1 $d
40008 40008 0 1 __do_global_dtors_aux_fini_array_entry
40010 40010 8 8 .init_array
40010 40010 8 8 crtbegin.o:(.init_array)
40010 40010 0 1 $d
40010 40010 0 1 __frame_dummy_init_array_entry
40018 40018 180 8 .dynamic
40018 40018 180 8 <internal>:(.dynamic)
40198 40198 8 8 .got
40198 40198 8 8 <internal>:(.got)
50000 50000 1 1 .bss
50000 50000 0 1 crt1.o:(.bss)
50000 50000 0 1 crti.o:(.bss)
50000 50000 1 1 crtbegin.o:(.bss)
50000 50000 1 1 completed.7557
50000 50000 0 1 $d
50001 50001 0 1 ./libs/libc_nonshared.a(elf-init.oS):(.bss)
50001 50001 0 1 crtend.o:(.bss)
50001 50001 0 1 crtn.o:(.bss)
0 0 24 1 .gnu_debuglink
0 0 c 1 crt1.o:(.gnu_debuglink)
c c c 1 crti.o:(.gnu_debuglink)
18 18 c 1 crtn.o:(.gnu_debuglink)
0 0 9d 1 .comment
0 0 9d 1 <internal>:(.comment)
0 0 5b8 8 .symtab
0 0 5b8 8 <internal>:(.symtab)
0 0 119 1 .shstrtab
0 0 119 1 <internal>:(.shstrtab)
0 0 228 1 .strtab
0 0 228 1 <internal>:(.strtab)
Ответы
Ответ 1
Вы должны скомпилировать с помощью опции -nodefaultlib
или -nostdlibs
.
Здесь цитата из документации GCC (clang-интерфейс такой же):
Одной из стандартных библиотек, обходящихся -nostdlib
и -nodefaultlibs
, является библиотека libgcc.a
, библиотека внутренних подпрограмм, которую GCC использует для преодоления недостатков конкретных машин или особых потребностей для некоторых языков.
Возможно, вам придется выполнять c++ статические инициализационные процедуры и/или использовать то, что предоставляется объектными файлами crt<x>.o
в каталоге lib. Эти файлы являются частью libc
и предоставляют исполняемую точку входа.
Ответ 2
Clang не приходит с компоновщиком, он полагается на ld
вместо этого. И ld
зависит от libgcc.a
и/или libgcc.so
от вашей системы (независимо от того, является ли LLVM-линкером ld.lld
или GNU ld). Именно по этой причине у вас есть это сообщение об ошибке.
Так что ответ на самом деле:
(a) линкер требует, чтобы libgcc выполнял свою собственную работу по связыванию
Более подробная информация об этом доступна здесь, на omniprog.info:
Если мы хотим избавиться от GCC и использовать clang как наш компилятор по умолчанию в системе, нам, возможно, придется внести некоторые корректировки в некоторые системы на основе RPM. Clang не предоставляет компоновщика, но полагается на компоновщик системы, обычно ld, для связывания исполняемых файлов. Это происходит даже в системах FreeBSD и Mac OS X, где Clang является компилятором по умолчанию. Мы можем увидеть это, используя опцию -v для clang++. Теперь ld не будет работать без следующих файлов:
libgcc.a
libgcc_s.so
[...]
Ответ 3
Так, на всякий случай
Я использую Qt и для запуска приложений на Android с версиями Qt более 5.11, имел эту проблему с последними Android Sdk и NDK-r20c. и после некоторой борьбы, наконец, он работал с NDK-r19c.