Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?
@cielavenir

MinGWでコンパイルしたC++バイナリのサイズ増加を抑える

libstdc++.dllを配布するのは面倒なので、libstdc++を静的リンクすることはよく行われると思う。
しかし、静的リンクするとそれだけでファイルサイズが600KBほど増加してしまう1,2

これはnmやマップファイルから当たりをつけることができて、このようなファイルをソースに加えると避けることができる3
x86_64-w64-mingw32-g++ -O2 src.cpp winexcept.cpp -static-libgcc -static-libstdc++ -sで確認済みです。

winexcept.cpp
#include <stdio.h>
#include <stdlib.h>
extern "C"{ static inline void puts_and_exit(const char* p){puts(p);exit(1);} }
namespace std{
    void __throw_bad_exception(){puts("bad_exception");exit(1);}
    void __throw_bad_alloc(){puts("bad_alloc");exit(1);}
    void __throw_bad_cast(){puts("bad_cast");exit(1);}
    void __throw_bad_typeid(){puts("bad_typeid");exit(1);}

    void __throw_logic_error(const char* p) __attribute((alias("puts_and_exit")));
    void __throw_domain_error(const char* p) __attribute((alias("puts_and_exit")));
    void __throw_invalid_argument(const char* p) __attribute((alias("puts_and_exit")));
    void __throw_length_error(const char* p) __attribute((alias("puts_and_exit")));
    void __throw_out_of_range(const char* p) __attribute((alias("puts_and_exit")));
    void __throw_out_of_range_fmt(const char* p, ...){puts(p);exit(1);}
    void __throw_runtime_error(const char* p) __attribute((alias("puts_and_exit")));
    void __throw_range_error(const char* p) __attribute((alias("puts_and_exit")));
    void __throw_overflow_error(const char* p) __attribute((alias("puts_and_exit")));
    void __throw_underflow_error(const char* p) __attribute((alias("puts_and_exit")));

    void __throw_ios_failure(const char* p) __attribute((alias("puts_and_exit")));
    void __throw_system_error(int n){printf("system_error %d\n",n);exit(1);}
    void __throw_future_error(int n){printf("future_error %d\n",n);exit(1);}
    void __throw_bad_function_call(){puts("bad_function_call");exit(1);}
}

# あ、iostream系使った場合は無力ですので、その辺はCで頑張るようにするしかありません。


  1. これはThread model: win32の場合であって、Thread model: posixの場合は実は大丈夫らしい。ただこの場合は-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamicなるおまじないが別途必要なのだが。ちなみにDebianではwin32版、macOS Homebrewではposix版がインストールされます。 

  2. http://www.mingw.org/wiki/Large_executables 

  3. 例外を握りつぶすということなので、「製品」では非推奨 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?