Why is GNU/Linux so Bloated?

Why is GNU/Linux so Bloated?

Shlomi Fish shlomif at iglu.org.il
Sun Jun 14 17:27:45 IDT 2009


On Sunday 14 June 2009 16:33:17 Nadav Har'El wrote:
> On Thu, Jun 11, 2009, Shlomi Fish wrote about "Re: Why is GNU/Linux so 
Bloated?":
> > I've compared the size of the Linux .so file (after -Os and strip) to the
> > size of the Windows MSVC-generated .dll.
> >
> > With gcc -Os before strip - 86,464 bytes
> > same after strip - 74,584
>
> Shlomi, what did you expect "strip" to do for the shared object? It
> definitely does not, and cannot, remove the *dynamic* symbol table which
> is needed to link this library. Try "nm -D" on your library to see the
> dynamic symbol table even after the strip. Is it possible that gcc saves a
> lot of crap in this symbol table that Windows doesn't?

With nm -D I'm getting:

{{{{{{{{{{{{{{
         w _Jv_RegisterClasses
         U __assert_fail
0000da64 A __bss_start
         U __ctype_b_loc
         U __ctype_toupper_loc
         w __cxa_finalize
         w __gmon_start__
0000da64 A _edata
0000da70 A _end
0000aec8 T _fini
00002658 T _init
         U atof
         U atoi
         U calloc
         U fclose
         U fgets
         U fopen
         U fread
         U free
00007cda T freecell_solver_user_alloc
00007b9b T freecell_solver_user_apply_preset
000040e9 T freecell_solver_user_cmd_line_parse_args
00003078 T freecell_solver_user_cmd_line_parse_args_with_file_nesting_count
00007fd7 T freecell_solver_user_current_state_as_string
00007b7f T freecell_solver_user_free
0000778f T freecell_solver_user_get_current_depth
00007ffc T freecell_solver_user_get_invalid_state_error_string
00007ab7 T freecell_solver_user_get_lib_version
00007873 T freecell_solver_user_get_limit_iterations
000078d3 T freecell_solver_user_get_max_num_decks
000078bf T freecell_solver_user_get_max_num_freecells
000078c9 T freecell_solver_user_get_max_num_stacks
00007881 T freecell_solver_user_get_moves_left
000080cf T freecell_solver_user_get_next_move
00007a73 T freecell_solver_user_get_num_soft_threads_in_instance
00007a40 T freecell_solver_user_get_num_states_in_collection
00007860 T freecell_solver_user_get_num_times
00007fb5 T freecell_solver_user_iter_state_as_string
0000777a T freecell_solver_user_limit_current_instance_iterations
000078ae T freecell_solver_user_limit_depth
0000776c T freecell_solver_user_limit_iterations
00007a4e T freecell_solver_user_limit_num_states_in_collection
000080c3 T freecell_solver_user_move_to_string
000080a1 T freecell_solver_user_move_to_string_w_state
00007f56 T freecell_solver_user_next_hard_thread
00007cf9 T freecell_solver_user_next_instance
00007f83 T freecell_solver_user_next_soft_thread
00007e7d T freecell_solver_user_recycle
00007cbc T freecell_solver_user_reset
00008127 T freecell_solver_user_resume_solution
00007981 T freecell_solver_user_set_a_star_weight
00007a81 T freecell_solver_user_set_calc_real_depth
00007947 T freecell_solver_user_set_empty_stacks_filled_by
000077c9 T freecell_solver_user_set_game
00007ecd T freecell_solver_user_set_hard_thread_prelude
000079ee T freecell_solver_user_set_iter_handler
000077c2 T freecell_solver_user_set_num_decks
000077b4 T freecell_solver_user_set_num_freecells
000077bb T freecell_solver_user_set_num_stacks
00007d8a T freecell_solver_user_set_optimization_scan_tests_order
00007a29 T freecell_solver_user_set_random_seed
00007a92 T freecell_solver_user_set_reparent_states
00007aa3 T freecell_solver_user_set_scans_synergy
00007917 T freecell_solver_user_set_sequence_move
000078dd T freecell_solver_user_set_sequences_are_built_by_type
00007f17 T freecell_solver_user_set_soft_thread_name
00007a5f T freecell_solver_user_set_soft_thread_step
0000789d T freecell_solver_user_set_solution_optimization
000077a0 T freecell_solver_user_set_solving_method
00007de4 T freecell_solver_user_set_tests_order
00008385 T freecell_solver_user_solve_board
         U fseek
         U ftell
         U getenv
         U malloc
         U memcmp
         U memmove
         U memset
         U pow
         U puts
         U qsort
         U realloc
         U sprintf
         U strchr
         U strcmp
         U strcpy
         U strdup
         U strncasecmp
         U strncmp
         U strncpy
         U vsprintf
}}}}}}}}}}}}}}

It's everything I expect it to be and not more - the external API and the 
functions it imports from libc. However, running strip on the MSVC-generated 
 .dll's generates a .dll under 20KB that also seems to be fully functional.

>
> Finally, I have no idea what your makefile looks like, but make sure that
> you do not accidentally statically-link the C library into your shared
> object. You'll want to dynamically-link it (to add a dependency), but not
> statically link it (which will add some actual code from the C library into
> your shared library).

I'm not statically linking libc. With libc statically linked, the .so is much 
larger:

{{{{{{{{{
$ ldd libfreecell-solver.so.0
        linux-gate.so.1 =>  (0xffffe000)
        libm.so.6 => /lib/i686/libm.so.6 (0xb7e81000)
        libc.so.6 => /lib/i686/libc.so.6 (0xb7d1d000)
        /lib/ld-linux.so.2 (0xb7ef3000)
}}}}}}}}

So all these factors still don't explain why the gcc-generated shared library 
binary is so much larger than MSVC's.

Regards,

	Shlomi Fish

-- 
-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
Best Introductory Programming Language - http://xrl.us/bjn84

God gave us two eyes and ten fingers so we will type five times as much as we
read.



More information about the Linux-il mailing list