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