Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: Yaroslav Dynnikov <yaroslav.dynnikov@tarantool.org>
Cc: tarantool-patches@dev.tarantool.org,
	Alexander Turenko <alexander.turenko@tarantool.org>
Subject: Re: [Tarantool-patches] [PATCH] cmake: cleanup src/CMakeLists.txt
Date: Sat, 20 Jun 2020 01:39:27 +0200	[thread overview]
Message-ID: <676d7330-579f-7950-896e-ae2b3bf7df9a@tarantool.org> (raw)
In-Reply-To: <CAK0MaD1b0qCBANHApfxya7hhQ8saU9L5cxYCgqEqV=3PJhWofg@mail.gmail.com>

Hi! Thanks for the investigation!

On 19/06/2020 15:02, Yaroslav Dynnikov wrote:
> I've researched the linking process and here is what I've found.
> 
> First of all, let's talk about symbols removal. Here is an interesting note on
> how it works: https://stackoverflow.com/questions/55130965/when-and-why-would-the-c-linker-exclude-unused-symbols
> One of the basic important concepts is an ELF section. It's a chunk of data
> (assembly code in our case) that linker operates on. A section may contain code
> of one or more functions (depending on build arguments), but it can't be split
> during linking.
> 
> Usually, when we build an object file with `gcc libx.c -c -o libx.o`, all
> functions from libx.c go into the single ".text" section. This single object
> file is usually archived with others into single libx.a, which is later
> processed during main executable linking.
> 
> By default (but I can't provide the proof), when we call `gcc -lx` linker
> operates on object files from the archive - if at least one symbol is used,
> whole .o (not .a) is included in the resulting binary. There are also two linker
> options that influence this behavior. At first, there is `-Wl,--whole-archive`,
> which makes it to include whole `.a` instead of `.o` granularity. Secondly, there is
> `-Wl,--gc-sections` which could remove unused sections, but in basic example
> it's useless since all symbols from .o belong to the same .text section. To make
> `--gc-sections` have an effect one should compile object files with
> `-ffunction-sections` flag. It'll generate a separate section for every function
> so the linker could gc unused ones.
> 
> See:
> ```console$ cat libx.c
> #include <stdio.h>
> 
> void fA() {
>         printf("fA is here\n");
> }
> void fB() {
>         printf("fB is here\n");
> }
> $ gcc libx.c -c -o libx.o -ffunction-sections
> $ readelf -S libx.o | grep .text
>   [ 1] .text             PROGBITS         0000000000000000  00000040
>   [ 5] .text.fA          PROGBITS         0000000000000000  00000056
>   [ 6] .rela.text.fA     RELA             0000000000000000  000002d8
>   [ 7] .text.fB          PROGBITS         0000000000000000  0000006d
>   [ 8] .rela.text.fB     RELA             0000000000000000  00000308
> ```
> 
> Now let's move to the `libbit` which Vlad mentioned.
> I've investigated how compiler options influence the resulting binary. Unused
> functions from bit.c are really remover, but only with Release flags, and here
> is why:
> 
> There are only 2 functions implemented in bit.c, and both are unused. All the
> others are inlines in bit.h and externs from luajit. When tarantool is built in
> debug mode, the inlining is off, so other modules truly link to the bit.o and
> all symbols remain including unused functions. But if we specify -O2 flag,
> inlining takes place, and all the symbols from bit.o becomes unused, so the
> linker drops the whole object file.

So do you mean, that if a library consists of more than 1 C file (and builds
more than one .o file), and functions from some of them are not used, these
.o files and their code will be removed?

If it is true, it does not look like green light for the patch and requires
more experiments. For example, try to add a new library with several C files,
use only some of them in the Tarantool executable (just add to exports.h),
and see if code from unused .o files is removed even when they are built into
.a file.

However, as I said in private - I am ok with pushing this patch now. I just
don't see why is it necessary. Why is it so important to push it? Push just
for push? Just to close an issue? It does not improve anything, EXPORT_LIST
still may appear to be useful along with some other things I removed in 2971,
when I didn't think of the static build.

> Finally, speaking about this patch, my proposal is to merge this PR as is.
> And since we know how to manage linking, other problems can be solved separately
> (if they ever occur).
> 
> Best regards
> Yaroslav Dynnikov

  reply	other threads:[~2020-06-19 23:39 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-11  0:25 HustonMmmavr
2020-06-14 21:34 ` Alexander Turenko
2020-06-15 17:27   ` Mavr Huston
2020-06-15 21:20 ` Vladislav Shpilevoy
2020-06-17 15:29   ` Mavr Huston
2020-06-17 23:09     ` Vladislav Shpilevoy
2020-06-19 13:02       ` Yaroslav Dynnikov
2020-06-19 23:39         ` Vladislav Shpilevoy [this message]
2020-06-23 20:31           ` Yaroslav Dynnikov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=676d7330-579f-7950-896e-ae2b3bf7df9a@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=alexander.turenko@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --cc=yaroslav.dynnikov@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH] cmake: cleanup src/CMakeLists.txt' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox