How do I fix this cmake file? - problem linking to

2019-05-22 08:13发布

问题:

I'm just starting out with cmake, and trying to set up a fairly simple project. Although the project itself is simple, it links to a number of static libraries which aren't built by cmake. They could be, I suppose - they are my libraries - but I need to sort out how to link to third party libraries anyway.

Here is what I have so far...

cmake_minimum_required(VERSION 2.8.1)
cmake_policy(VERSION 2.8.1)

project( test01 )

include_directories("../../cpplib/sh_core" "../../cpplib/sh_core2" "../../cpplib/sh_genlib")

link_directories("../../cpplib/_vc_debug")

add_library( sh_core   STATIC IMPORTED )
add_library( sh_core2  STATIC IMPORTED )
add_library( sh_genlib STATIC IMPORTED )

add_executable( test01 test01 test01_ast test01_parse test01_scan test01_main )
target_link_libraries(test01 sh_core sh_core2 sh_genlib)

The problem is that the three libraries that I'm trying to link to aren't being referenced correctly in the generated project file. They are listed as sh_core-NOTFOUND, sh_core2-NOTFOUND and sh_genlib-NOTFOUND.

I think perhaps I don't need the link_directories from above, but I do need a find_library command. But I've taken a quick look at that command in the docs and... WTF!!! I already have a headache, and I really can't cope with that mass of seemingly redundant complexity ATM. Besides, seeing this much complexity for something that should be perfectly simple suggests to me that I'm looking in the wrong place.

So... how do I tell cmake where to find those libraries?

Bonus question - how do I set this up so the generated project handles both a debug build and a release build? Note - the release versions of the imported libraries have the same filenames, but are in a "../../cpplib/_vc_release" folder.

回答1:

I think you've misunderstood the include_directories and add_library directives.

include_directories adds directories to be searched for include files, while add_library can be used like this (in your case):

add_library(core UNKNOWN IMPORTED)
set_target_properties(core PROPERTIES IMPORTED_LOCATION "../../cpplib/_vs_release/core.lib")

However, if I correctly understand what you're trying to accomplish, something like this should do it:

set(CPPLIB_DIR "${CMAKE_SOURCE_DIR}/../../cpplib")

set(CPPLIB_DEBUG_DIR "${CPPLIB_DIR}/_vc_debug")
set(CPPLIB_RELEASE_DIR "$(CPPLIB_DIR}/_vc_release")

if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
    set(CPPLIB_LIB_HINT ${CPPLIB_RELEASE_DIR})
else ()
    set(CPPLIB_LIB_HINT ${CPPLIB_DEBUG_DIR})
endif ()

find_library(CPPLIB_CORE_LIBRARY NAMES "core"
                                 PATHS ${CPPLIB_LIB_HINT})

find_library(CPPLIB_CORE2_LIBRARY NAMES "core2"
                                  PATHS ${CPPLIB_LIB_HINT})

find_library(CPPLIB_GENLIB_LIBRARY NAMES "genlib"
                                   PATHS ${CPPLIB_LIB_HINT})

if (("${CPPLIB_CORE_LIBRARY}" STREQUAL "CPPLIB_CORE_LIBRARY-NOTFOUND") OR
    ("${CPPLIB_CORE2_LIBRARY}" STREQUAL "CPPLIB_CORE2_LIBRARY-NOTFOUND") OR
    ("${CPPLIB_GENLIB_LIBRARY}" STREQUAL "CPPLIB_GENLIB_LIBRARY-NOTFOUND"))
    message(FATAL_ERROR "One of the libs wasn't found!")
endif ()

set(CPPLIB_LIBRARIES ${CPPLIB_CORE_LIBRARY} ${CPPLIB_CORE2_LIBRARY} ${CPPLIB_GENLIB_LIBRARY})

target_link_libraries(my_exe ${CPPLIB_LIBRARIES})

EDIT: If you also want to include some headers, it's as simple as:

find_path(CPPLIB_INCLUDE_DIR "my_header.h"
    PATHS ${CPPLIB_HINT_INCLUDE_DIR})

...

include_directories(${CPPLIB_INCLUDE_DIR})


回答2:

A followup on the_void's answer:

You should be able to simplify the if test expression which reads:

if (("${CPPLIB_CORE_LIBRARY}" STREQUAL "CPPLIB_CORE_LIBRARY-NOTFOUND") OR
    ("${CPPLIB_CORE2_LIBRARY}" STREQUAL "CPPLIB_CORE2_LIBRARY-NOTFOUND") OR
    ("${CPPLIB_GENLIB_LIBRARY}" STREQUAL "CPPLIB_GENLIB_LIBRARY-NOTFOUND"))
    message(FATAL_ERROR "One of the libs wasn't found!")
endif ()

to be something like this:

if (CPPLIB_CORE_LIBRARY OR
    CPPLIB_CORE2_LIBRARY OR
    CPPLIB_GENLIB_LIBRARY)
    message(FATAL_ERROR "One of the libs wasn't found!")
endif ()

Reference CMake's if statement.



标签: cmake