[CMake] making two targets with similar names

Philip Lowman philip at yhbt.com
Fri Aug 10 18:44:06 EDT 2007


Juan Sanchez wrote:
> I am having the following issue.  I want to create both a libFOO.a and a
> libFOO.so.  Note that the libFOO.so is composed of more sources than the
> libFOO.a.
> 
> I use OUTPUT_NAME in order so they have the same name.  I can make the
> FOOSTATIC, libFOO.a, target, just fine.  However, making the FOODYNAMIC,
> libFOO.so, target deletes libFOO.a, just before linking against it.
> This causes a build error.
> 
> Is there anyway to prevent this from happening?
> 
> 
> ADD_LIBRARY (FOOSTATIC  STATIC ${UDB_SRCS})
> ADD_LIBRARY (FOODYNAMIC SHARED ${PERL_SRCS})

I had the same problem but on a greater scale because I wanted all of
our libraries to be able to built either statically or dynamically and I
wanted it to be able to happen in the same build.  The best solution I
came up with was to simply wrap every call to ADD_LIBRARY,
ADD_EXECUTABLE, and TARGET_LINK_LIBRARIES.  Static targets get "-static"
appended to them and shared targets get "-shared" appended.  Then I used
a "global" variable called LIB_TYPES to control whether I wanted static
and/or shared libraries built.

Probably overkill for your needs but here it is anyways...


#-------------------------------------------------------------------------
# MST_ADD_LIBRARY.
#-------------------------------------------------------------------------
#
# A wrapper for ADD_LIBRARY that gracefully handles creating static
# and shared library targets depending on the value of the list variable
# LIB_TYPES.
#
# If LIB_TYPES contains STATIC this function defines a static library
# target called ${library}-static
# If it contains SHARED ${library}-shared will be linked.
#
MACRO(MST_ADD_LIBRARY library)
    FOREACH(type ${LIB_TYPES})
        STRING(TOLOWER ${type} lc_type)
        STRING(REGEX REPLACE "^sim" "" label ${library})

        ADD_LIBRARY(${library}-${lc_type} ${type} ${ARGN})
        SET_TARGET_PROPERTIES(${library}-${lc_type} PROPERTIES
PROJECT_LABEL ${label})
        SET_TARGET_PROPERTIES(${library}-${lc_type} PROPERTIES
OUTPUT_NAME ${library})
        SET_TARGET_PROPERTIES(${library}-${lc_type} PROPERTIES
CLEAN_DIRECT_OUTPUT 1)

    ENDFOREACH()
ENDMACRO(MST_ADD_LIBRARY)

#-------------------------------------------------------------------------
# MST_ADD_EXECUTABLE.
#-------------------------------------------------------------------------
#
# A macro for creating one or two command line executable targets depending
# on the contents of the list variable BIN_TYPES.
#
# If BIN_TYPES contains STATIC, a static target is generated called
# ${mytarget}-static and the binary is built as ${mytarget}.
#
# If BIN_TYPES contains SHARED, a shared target is generated called
# ${mytarget}-shared and the binary is built as ${mytarget}.
#
# If BIN_TYPES contains both, the output name on the resulting targets is
# overriden to be ${mytarget}_static and ${mytarget}_shared resulting in:
#
# foo_static.exe
# foo_shared.exe
#
# This is meant to prevent overlap in the rare case when shared and static
# binaries are meant to be built concurrently.  If the user doesn't like
this
# they can defined their own target names using ADD_EXECUTABLE.
#
MACRO(MST_ADD_EXECUTABLE mytarget)

    FOREACH(type ${BIN_TYPES})
        STRING(TOLOWER ${type} lc_type)

        ADD_EXECUTABLE(${mytarget}-${lc_type} ${ARGN})
        SET_TARGET_PROPERTIES(${mytarget}-${lc_type} PROPERTIES
OUTPUT_NAME ${mytarget})
        SET_TARGET_PROPERTIES(${mytarget}-${lc_type} PROPERTIES
PROJECT_LABEL ${mytarget})
    ENDFOREACH()

    # This forces executable filename to be foo_static and foo_shared
    # in the event the user wants both a static and shared target.
    IF("${BIN_TYPES}" MATCHES "STATIC" AND "${BIN_TYPES}" MATCHES "SHARED")
        SET_TARGET_PROPERTIES(${mytarget}-static PROPERTIES OUTPUT_NAME
${mytarget}_static)
        SET_TARGET_PROPERTIES(${mytarget}-static PROPERTIES
PROJECT_LABEL ${mytarget}-static)

        SET_TARGET_PROPERTIES(${mytarget}-shared PROPERTIES OUTPUT_NAME
${mytarget}_shared)
        SET_TARGET_PROPERTIES(${mytarget}-shared PROPERTIES
PROJECT_LABEL ${mytarget}-shared)
    ENDIF()
ENDMACRO(MST_ADD_EXECUTABLE)

#-------------------------------------------------------------------------
# MST_LINK_LIBRARY_AGAINST_EXTERNAL_LIBS.
#-------------------------------------------------------------------------
#
# A wrapper for TARGET_LINK_LIBRARIES that allows a static or shared library
# to be linked against a variety of external libraries.
#
# If LIB_TYPES contains STATIC this function will link the target
# ${library}-static against all subsequent arguments passed into the
function.
# If it contains SHARED ${library}-shared will be linked.
#
MACRO(MST_LINK_LIBRARY_AGAINST_EXTERNAL_LIBS library)
    FOREACH(type ${LIB_TYPES})
        STRING(TOLOWER ${type} lc_type)

        TARGET_LINK_LIBRARIES(${library}-${lc_type} ${ARGN})

    ENDFOREACH()
ENDMACRO(MST_LINK_LIBRARY_AGAINST_EXTERNAL_LIBS)

#-------------------------------------------------------------------------
# MST_LINK_LIBRARY_AGAINST_INTERNAL_LIBS.
#-------------------------------------------------------------------------
#
# A wrapper for TARGET_LINK_LIBRARIES that allows a static or shared library
# to be linked against a corresponding static or shared library built
# internally.
#
# This allows you to link internally built static library targets against
# other static targets and vice versa for shared libraries depending on the
# variable LIB_TYPES when this function is called.
#
MACRO(MST_LINK_LIBRARY_AGAINST_INTERNAL_LIBS library)
    FOREACH(type ${LIB_TYPES})
        STRING(TOLOWER ${type} lc_type)

        FOREACH(arg ${ARGN})
            TARGET_LINK_LIBRARIES(${library}-${lc_type} ${arg}-${lc_type})
        ENDFOREACH()

    ENDFOREACH()
ENDMACRO(MST_LINK_LIBRARY_AGAINST_INTERNAL_LIBS)

#-------------------------------------------------------------------------
# MST_LINK_BINARY_AGAINST_EXTERNAL_LIBS.
#-------------------------------------------------------------------------
#
# Convenience macro to be consistent.
#
MACRO(MST_LINK_BINARY_AGAINST_EXTERNAL_LIBS target)
    MST_LINK_LIBRARY_AGAINST_EXTERNAL_LIBS(${target} ${ARGN})
ENDMACRO(MST_LINK_BINARY_AGAINST_EXTERNAL_LIBS)

#-------------------------------------------------------------------------
# MST_LINK_BINARY_AGAINST_INTERNAL_LIBS.
#-------------------------------------------------------------------------
#
# A wrapper for TARGET_LINK_LIBRARIES that facilitates linking a
# binary target against either static or shared libraries.  This linking is
# directed via the BIN_TYPES variable.
#
# If BIN_TYPES contains STATIC the target will be linked against static
# libraries.  If BIN_TYPES contains SHARED the target will be linked against
# shared libraries.
#
MACRO(MST_LINK_BINARY_AGAINST_INTERNAL_LIBS mytarget)
    FOREACH(type ${BIN_TYPES})
        STRING(TOLOWER ${type} lc_type)

        FOREACH(arg ${ARGN})
            TARGET_LINK_LIBRARIES(${mytarget}-${lc_type} ${arg}-${lc_type})
        ENDFOREACH()

    ENDFOREACH()
ENDMACRO(MST_LINK_BINARY_AGAINST_INTERNAL_LIBS)


-- 
Philip Lowman
Simulation Development Engineer, Modeling and Simulation Technology
General Dynamics Land Systems
http://www.gdls.com


More information about the CMake mailing list