Search code examples
c++gccautoconfautomakelibtool

how to create binary and .so using libtool


I have a set of cpp files that I want to compile directly into a binary and also to compile into a shared library.

I have

bin_PROGRAMS=mybin
lib_LTLIBRARIES=libmylib.la

COMMON_SOURCES=f1.cpp f2.cpp f3.cpp

mybin_SOURCES=main.cpp $(COMMON_SOURCES)
libmylib_la_SOURCES=$(COMMON_SOURCES)

When I run this the cpp files are compiled twice, once with libtool and once without and sometimes libtool/automake complains

Makefile.am: object `f1.$(OBJEXT)' created both with libtool and without`

I tried putting COMMON_SOURCES into a .a file but then libtool complains when I link a .a with a .la (saying its not portable).

What I need is something like

bin_LTPROGRAMS=mybin

but that doesnt exist

edit: clarification - I am using automake/autoconf. What I have shown above is the meat of my automake Makefile.am


Solution

  • The issue is that the common sources need to be compiled differently when they are being made into a shared object than when they are being made into a static archive; in the case of the former, for example, g++ needs to be passed the -fPIC flag.

    What I suggest is using two build directories.

    Assuming this source hierarchy:

    ./src/Makefile.am
    ./src/f1.cpp
    ./src/f2.cpp
    ./src/f3.cpp
    ./src/main.cpp
    ./configure.ac
    ./Makefile.am
    

    you would use something like this in ./src/Makefile.am:

    bin_PROGRAMS = mybin
    lib_LTLIBRARIES = libmylib.la
    
    mybin_SOURCES = main.cpp
    mybin_LDADD = libmylib.la
    
    libmylib_la_SOURCES = f1.cpp f2.cpp f3.cpp
    

    Then you create directories Release and ReleaseDisableShared in ./. In directory ./Release you run:

    ../configure && make
    

    and in ./ReleaseDisableShared you run:

    ../configure --disable-shared && make
    

    After building in each build directory, you use the mybin at ./ReleaseDisableShared/src/mybin and the libmylib.so at ./Release/src/libmylib.so.

    See also: