[CMake] How to have a static/shared option in a Find script ?

Michael Hertling mhertling at online.de
Thu Feb 16 11:18:23 EST 2012


On 02/16/2012 03:14 PM, Barth wrote:
> Hi again,
> 
> I have understood what you meant :)

Hhm, actually, I talked nonsense w.r.t. DIM_USE_STATIC. ;)

> For records here is what I did :
> 
> # (1) Use FIND_LIBRARY() to look for the shared and the static library
> #     and define DIM_SHARED_LIBRARY and DIM_STATIC_LIBRARY in the cache. 
> find_library(DIM_STATIC_LIBRARY NAMES libdim.a PATHS $ENV{DIMDIR}
> PATH_SUFFIXES linux)
> find_library(DIM_SHARED_LIBRARY NAMES dim PATHS $ENV{DIMDIR} PATH_SUFFIXES
> linux)

If libdim.so doesn't exist, but libdim.a does, the last FIND_LIBRARY()
call would return libdim.a, too, which is probably not desired. Here,
one should consider to narrow the search for the respective library
type, e.g. by manipulating CMAKE_FIND_LIBRARY_SUFFIXES; see also
CMAKE_{SHARED,STATIC}_LIBRARY_{PREFIX,SUFFIX} in this regard.

> # (2) Inspect DIM_FIND_COMPONENTS to see which flavor has been requested,
> #     defaulting to "shared" if no components have been requested at all. 
> LIST(FIND DIM_FIND_COMPONENTS static ASK_STATIC_COMP) 
> LIST(FIND DIM_FIND_COMPONENTS shared ASK_SHARED_COMP) 

No need for them; use DIM_FIND_REQUIRED_{STATIC,SHARED} - predefined
by FIND_PACKAGE(). Refer to Modules/readme.txt for more information.

> # (3) Warn or bail out if "shared" and "static" have both been requested
> if ( ${ASK_STATIC_COMP} GREATER -1 AND ${ASK_SHARED_COMP} GREATER -1)
>     message(WARNING "Two incompatible components specified : static and
> shared. We are going to ignore the static component.")
> endif ( ${ASK_STATIC_COMP} GREATER -1 AND ${ASK_SHARED_COMP} GREATER -1)

IF(DIM_FIND_REQUIRED_SHARED AND DIM_FIND_REQUIRED_STATIC)
    MESSAGE(WARNING ...)
    LIST(REMOVE_ITEM DIM_FIND_COMPONENTS static)
    UNSET(DIM_FIND_REQUIRED_STATIC)
ENDIF()

Do something to the contrary if DIM_FIND_COMPONENTS is empty:

IF(NOT DIM_FIND_COMPONENTS)
    LIST(APPEND DIM_FIND_COMPONENTS shared)
    SET(DIM_FIND_REQUIRED_SHARED TRUE)
ENDIF()

The point is that DIM_FIND_COMPONENTS and DIM_FIND_REQUIRED_* are set
up properly *before* you are going to actually enable the components.

> # (4) DIM_USE_STATIC decides if DIM_LIBRARIES receives DIM_STATIC_LIBRARY
> #     or DIM_SHARED_LIBRARY
> option(DIM_FORCE_STATIC "Turn on to force the use of the static library"
> OFF)
> if( ${DIM_FORCE_STATIC} OR ${ASK_STATIC_COMP} GREATER -1) 
>     set(DIM_LIBRARIES ${DIM_STATIC_LIBRARY} )
> else ( ${DIM_FORCE_STATIC} OR ${ASK_STATIC_COMP} GREATER -1) 
>     set(DIM_LIBRARIES ${DIM_SHARED_LIBRARY} )
> endif( ${DIM_FORCE_STATIC} OR ${ASK_STATIC_COMP} GREATER -1) 

UNSET(DIM_INCLUDE_DIRS)
UNSET(DIM_LIBRARIES)

SET(DIM_FOUND FALSE)

FIND_PATH(DIM_INCLUDE_DIR ...)

IF(DIM_INCLUDE_DIR)
    SET(DIM_FOUND TRUE)
ENDIF

IF(DIM_FIND_REQUIRED_SHARED)
    FIND_LIBRARY(DIM_SHARED_LIBRARY ...)
    FIND_PACKAGE_HANDLE_STANDARD_ARGS(
        DIM_SHARED
        DEFAULT_MSG
        DIM_INCLUDE_DIR
        DIM_SHARED_LIBRARY)
    IF(DIM_SHARED_FOUND)
        LIST(APPEND DIM_INCLUDE_DIRS ${DIM_INCLUDE_DIR} ...)
        LIST(APPEND DIM_LIBRARIES ${DIM_SHARED_LIBRARY} ...)
   ENDIF()
   LIST(REMOVE DIM_FIND_COMPONENTS shared)
   UNSET(DIM_FIND_REQUIRED_SHARED)
ENDIF()

IF(DIM_FIND_REQUIRED_STATIC)
    FIND_LIBRARY(DIM_STATIC_LIBRARY ...)
    FIND_PACKAGE_HANDLE_STANDARD_ARGS(
        DIM_STATIC
        DEFAULT_MSG
        DIM_INCLUDE_DIR
        DIM_STATIC_LIBRARY)
    IF(DIM_STATIC_FOUND)
        LIST(APPEND DIM_INCLUDE_DIRS ${DIM_INCLUDE_DIR} ...)
        LIST(APPEND DIM_LIBRARIES ${DIM_STATIC_LIBRARY} ...)
   ENDIF()
   LIST(REMOVE DIM_FIND_COMPONENTS static)
   UNSET(DIM_FIND_REQUIRED_STATIC)
ENDIF()

# Consider to handle remaining components in DIM_FIND_COMPONENTS.

Note that due to the preparatory work on DIM_FIND_COMPONENTS and the
DIM_FIND_REQUIRED_* variables, the blocks for enabling the shared and
static component have a straight forward structure. Note further that
this can be achieved only with a quite simple package like yours with
two mutually exclusive libraries; with packages providing more subtly
related components - e.g. with inter-component dependencies - things
can be much more complicated. Note finally that the user must issue

IF(DIM_FOUND AND DIM_SHARED_FOUND)

e.g., in order to check for the library's availability unless the
REQUIRED flag was given to FIND_PACKAGE(). Checking for DIM_FOUND
or DIM_SHARED_FOUND alone is *not* reliable, just as referring to
a component that hasn't been requested explicitly - or enabled by
default which, in turn, should be documented explicitly.

Regards,

Michael


More information about the CMake mailing list