Question for static linking

Help
kaienfr
2012-11-01
2013-06-06
  • kaienfr
    kaienfr
    2012-11-01

    I have a project which requires gcc, g++, and gfortran for compiling since there are C/C++/Fortran codes.
    I tried Mingw-w64 4.6.x on ubuntu  to compile and link the project, and found that it's always gives shared version by default. i.e., I need to copy some dll files from the lib folder to windows to make the exe file run.

    I've tried setting options -enable-static -disable-shared for configure, that not works.
    I've also tried options CFLAGS='-static' CXXFLAGS='-static' FFLAGS='-static' for configure, not works neither.
    I've tried again CFLAGS='-static-libgcc' CXXFLAGS='-static-libstdc++ -static-libgcc' FFLAGS='-static-libgfortran', while not works again…
    It seems that after 'configure', it always built a makefile linking to -lgcc_s and shared libgfortran.

    In order to force a static link, what I did now is to rename the libs: libgcc_s.a, libgfortran.dll.a, libquadmath.dll.a, libstdc++.dll.a, and copy libgcc.a to libgcc_s.a (since -lgcc_s is always presented in makefile after configure).
    And configure with options CFLAGS='-static-libgcc' CXXFLAGS='-static-libstdc++ -static-libgcc'
    This time, it works. If configure without  -static-libstdc++ -static-libgcc it does not work.

    I'd like to know, is there a standard way to set options to configure for build a static exe?
    Any suggestion? Thanks in advance!

    Here is the complementary information for GCC
    $ x86_64-w64-mingw32-gcc -v
    Using built-in specs.
    COLLECT_GCC=x86_64-w64-mingw32-gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-w64-mingw32/4.6/lto-wrapper
    Target: x86_64-w64-mingw32
    Configured with: ../../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/include' --mandir='/usr/share/man' --infodir='/usr/share/info' --sysconfdir=/etc --localstatedir=/var --libexecdir='/usr/lib/gcc-mingw-w64' --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --enable-shared --enable-static --disable-multilib --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --libdir=/usr/lib --enable-libstdcxx-time=yes --with-tune=generic --enable-version-specific-runtime-libs --enable-threads=win32 --enable-fully-dynamic-string --enable-sjlj-exceptions --enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-lto --with-plugin-ld --target=x86_64-w64-mingw32 --with-gxx-include-dir=/usr/include/c++/4.6 --with-as=/usr/bin/x86_64-w64-mingw32-as --with-ld=/usr/bin/x86_64-w64-mingw32-ld
    Thread model: win32
    gcc version 4.6.3 (GCC) 
    $ x86_64-w64-mingw32-g++ -v
    Using built-in specs.
    COLLECT_GCC=x86_64-w64-mingw32-g++
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-w64-mingw32/4.6/lto-wrapper
    Target: x86_64-w64-mingw32
    Configured with: ../../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/include' --mandir='/usr/share/man' --infodir='/usr/share/info' --sysconfdir=/etc --localstatedir=/var --libexecdir='/usr/lib/gcc-mingw-w64' --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --enable-shared --enable-static --disable-multilib --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --libdir=/usr/lib --enable-libstdcxx-time=yes --with-tune=generic --enable-version-specific-runtime-libs --enable-threads=win32 --enable-fully-dynamic-string --enable-sjlj-exceptions --enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-lto --with-plugin-ld --target=x86_64-w64-mingw32 --with-gxx-include-dir=/usr/include/c++/4.6 --with-as=/usr/bin/x86_64-w64-mingw32-as --with-ld=/usr/bin/x86_64-w64-mingw32-ld
    Thread model: win32
    gcc version 4.6.3 (GCC) 
    $ x86_64-w64-mingw32-gfortran -v
    Using built-in specs.
    COLLECT_GCC=x86_64-w64-mingw32-gfortran
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-w64-mingw32/4.6/lto-wrapper
    Target: x86_64-w64-mingw32
    Configured with: ../../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/include' --mandir='/usr/share/man' --infodir='/usr/share/info' --sysconfdir=/etc --localstatedir=/var --libexecdir='/usr/lib/gcc-mingw-w64' --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --enable-shared --enable-static --disable-multilib --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --libdir=/usr/lib --enable-libstdcxx-time=yes --with-tune=generic --enable-version-specific-runtime-libs --enable-threads=win32 --enable-fully-dynamic-string --enable-sjlj-exceptions --enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-lto --with-plugin-ld --target=x86_64-w64-mingw32 --with-gxx-include-dir=/usr/include/c++/4.6 --with-as=/usr/bin/x86_64-w64-mingw32-as --with-ld=/usr/bin/x86_64-w64-mingw32-ld
    Thread model: win32
    gcc version 4.6.3 (GCC)
    
     
  • kaienfr
    kaienfr
    2012-11-01

    PS: I need to link with static  libquadmath.a too, how to set it in options for configure?

     
  • rubenvb
    rubenvb
    2012-11-01

    The configure option you are looking for is:

    LDFLAGS=-static
    

    Which signals the linker to use static libraries where possible. Your toolchain was built with -enable-static so it should contain static versions of all the runtime libraries.

     
  • kaienfr
    kaienfr
    2012-11-01

    Thanks rubenvb for your suggestion.
    I've just tried it, but the resulting exe still require libgcc_s_sjlj-1.dll
    Here is the commands I used:

    mkdir buildwin32
    cd buildwin32
    ../configure -C --prefix=$HOME/Win32-install --host=i686-w64-mingw32 LDFLAGS='-static'
    make
    

    The toolchain information is given as follows:

    $ i686-w64-mingw32-gcc -v
    Using built-in specs.
    COLLECT_GCC=i686-w64-mingw32-gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-w64-mingw32/4.6/lto-wrapper
    Target: i686-w64-mingw32
    Configured with: ../../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/include' --mandir='/usr/share/man' --infodir='/usr/share/info' --sysconfdir=/etc --localstatedir=/var --libexecdir='/usr/lib/gcc-mingw-w64' --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --enable-shared --enable-static --disable-multilib --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --libdir=/usr/lib --enable-libstdcxx-time=yes --with-tune=generic --enable-version-specific-runtime-libs --enable-threads=win32 --enable-fully-dynamic-string --enable-sjlj-exceptions --enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-lto --with-plugin-ld --target=i686-w64-mingw32 --with-gxx-include-dir=/usr/include/c++/4.6 --with-as=/usr/bin/i686-w64-mingw32-as --with-ld=/usr/bin/i686-w64-mingw32-ld
    Thread model: win32
    gcc version 4.6.3 (GCC)
    

    I opened a Makefile and found that the linked libgcc is -lgcc_eh if I use LDFLAGS=-static option, otherwise, I will get -lgcc_s. But what I need is -lgcc. What should I do now? Thanks a lot in advance!

     
  • rubenvb
    rubenvb
    2012-11-01

    Then the project's build system is messed up somehow. What project is this? Then I can see what is going wrong. A project's Makefile shouldn't link the GCC runtime libraries itself anyways, unless it's adding e.g. the libgfortran library to link with a C++ application or libstdc++ for a fortran app.

    If you link a final executable with "-static" and the toolchain was built with -enable-static, you get zero dependency on libgcc, libstdc++, and libgfortran dll's, and instead have the code linked in statically.

     
  • kaienfr
    kaienfr
    2012-11-01

    The project is Coin-or Couenne, https://projects.coin-or.org/Couenne
    You could get source by svn:

    svn co https://projects.coin-or.org/svn/Couenne/stable/0.4 Couenne
    

    Before configure the project, you should get some thirdparties, you just need to enter ThirdParty folder and get
    ASL, BLAS, Lapack and  Mumps by simply running the script 'get.xxxx' in their folders. Only these four terms are needed, the others are optional, you do not need to get them.

    Once you get these 3rd parties, you can run configure to build makefiles and then make them.
    I build on ubuntu with mingw-w64 gcc 4.6.3 targeting win32 and win64.
    (As what you said, this project indeed link libgfortran with a C++ application since fortran libs: blas and lapack are required.)
    Looking forward to your help. Thanks a lot.

     
  • rubenvb
    rubenvb
    2012-11-18

    Sorry for the delay, I've been out of time lately.

    With all the 3rdparty dependencies, it'll be hard to track down which one is pulling in the DLLs. All of these need to be built as static explicitly as well. I'm not sure how lenient BLAS etc. are to being built statically on Windows…