[CMake] Can't build static binary

Nikita V. Borodikhin nikita at pictures.uniqueics.com.ru
Wed May 23 13:39:39 EDT 2007


Hello, all!

There is a problem in CMake, at least in version 2.4.6 on Linux.

I want to build dynamically-linked binary while I test my program but
want to build static one to distibute it to customers.

The problem arises when my binary is built using libraries.
Generated Makefile rule includes linker-specific command to link to
static library (-Wl,-Bstatic), that's alright but it _always_ includes
command -Wl,-Bdynamic after all the libraries specified.
It looks like this:
  /usr/bin/gcc -O3 -DNDEBUG -fPIC "CMakeFiles/tst.dir/tst.o"
  -o tst -rdynamic -L/tmp/a/b -Wl,-Bstatic -ltstlib -Wl,-Bdynamic
  -Wl,-rpath,/tmp/a/b
When passing command to linker GCC adds its standard libraries (-lgcc
-lgcc_eh -lc) _after_ last argument.

So I can't build static binary because standard GCC libraries are linked
dynamically. Moreover, if I specify -static in CMAKE_EXE_LINKER_FLAGS, I
get broken binary which even doesn't run. The only way to build what I
need is to redefine variable that holds this linker instruction,
CMAKE_EXE_LINK_DYNAMIC_${LANG}_FLAGS.

The problem is in cmOrderLinkDirectories.cxx, it always adds default
link type argument at line 322:
  this->SetCurrentLinkType(this->StartLinkType)
but StartLinkType is always set to shared in cmLocalGenerator.cxx:
  orderLibs.SetLinkTypeInformation(cmOrderLinkDirectories::LinkShared,
                                   static_link_type_flag,
                                   shared_link_type_flag);

I think this problem could be resolved by adding executable property
about requested build type - static or dynamic and calling
SetLinkTypeInformation with appropriate parameter.


Small exmaple which leads to broken release binary until second line in
CMakeLists.txt is uncommented:

tst.c:
==========
#include <stdio.h>

int main ()
{
  printf ("Hi!\n");
}
==========

lib.c:
==========
void foo ()
{
}
==========

CMakeLists.txt:
==========
SET (CMAKE_EXE_LINKER_FLAGS_RELEASE "-static")
#SET (CMAKE_EXE_LINK_DYNAMIC_C_FLAGS "")

ADD_LIBRARY (tstlib lib.c)

ADD_EXECUTABLE (tst tst.c)
TARGET_LINK_LIBRARIES (tst tstlib)
==========

-- 
Nikita V. Borodikhin, NIKB-RIPN BNV7-RIPE
Registered Linux user #256562 with the Linux Counter
uniqueics.com.ru


More information about the CMake mailing list