0

Now my CMakeList.txt looking like this.

cmake_minimum_required(VERSION 3.6)
project(RabbitMQClient)

set(CMAKE_CXX_STANDARD 11)

set(SOURCE_FILES main.cpp)
include_directories(src)
include_directories(dependentFile)
add_executable(RabbitMQClient ${SOURCE_FILES})
find_library(SimpleAmqpClient SimpleAmqpClient.2.lib PATHS ./SimpleAmqpClientLib/SimpleAmqpClient.2.lib)
set(IMPORTED_IMPLIB ./SimpleAmqpClientLib)
target_link_libraries(RabbitMQClient PUBLIC SimpleAmqpClient)

when Linking the RabbitMQClient it complains.

cannot find -lSimpleAmqpClient

I want to use the SimpleAmqpClient library in the project,however not quite familiar with cmake not sure the find_library,IMPORTED_IMPLIB,PUBLIC in target_link_libraries was correctly used.Any help would be appreciate.

Shihe Zhang
  • 2,641
  • 5
  • 36
  • 57

1 Answers1

4

You have messed up with variables, targets and properties.

Proper usage of IMPORTED libraries for linking would be:

# This command sets *variable* SimpleAmqpClient_LIBRARY
find_library(SimpleAmqpClient_LIBRARY SimpleAmqpClient.2.lib
    PATHS ${CMAKE_SOURCE_DIR}/SimpleAmqpClientLib # Specify a *directory*, not a library *file*
)
# Next, create an IMPORTED *target*
add_library(SimpleAmqpClient SHARED IMPORTED)
# And set IMPORTED_LIB *property* for this target
set_target_properties(SimpleAmqpClient PROPERTIES IMPORTED_LIB ${SimpleAmqpClient_LIBRARY})
# Then use library *target* for linking with
target_link_libraries(RabbitMQClient PUBLIC SimpleAmqpClient)

However, there some simplifications which could be done:

  1. Normally, find_library is used when you don't know complete path to the library file. E.g., its directory may be different on different machines, or its prefix/extension may be different on different plaforms.

    If you know complete path to the library, just use this path directly (e.g., assign it to the variable).

  2. Normally, property IMPORTED_LOCATION is used for specify library to link with. Property IMPORTED_LIB is specific for Windows .dlls, when linking requires not a library file (.dll), but some other one (.lib).

    However, CMake perfectly understands .lib file in IMPORTED_LOCATION property even for Windows .dlls, so your code need not distinguish SHARED Windows libraries from others: just use IMPORTED_LOCATION property in all cases.

Simplified version of the code:

# Create an IMPORTED library *target*
add_library(SimpleAmqpClient IMPORTED)
# Set IMPORTED_LOCATION *property* for this target
set_target_properties(SimpleAmqpClient PROPERTIES
    IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/SimpleAmqpClientLib/SimpleAmqpClient.2.lib)
# Then use library *target* for linking with
target_link_libraries(RabbitMQClient PUBLIC SimpleAmqpClient)
Community
  • 1
  • 1
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • After the simplified version `add_library(SimpleAmqpClient IMPORTED)` add `STATIC` it works fine.Thank you! – Shihe Zhang May 17 '17 at 08:37
  • after cmake config pass, linking issue error `undefined reference to `_imp___ZN10AmqpClient`.Is the problem on cmake config? – Shihe Zhang May 17 '17 at 10:31
  • This looks like **incompatibility** between precompiled library and compiler/linker used for compile the application. – Tsyvarev May 17 '17 at 11:34
  • Yes,the precompiled library was built by msvc and the current project is using mingw. How do you diagnose that? – Shihe Zhang May 18 '17 at 00:38