Linking external libraries

Answered

I have been using Visual Studio for my C++ development. But, I made the decision to try out CLion and cmake. I am having issues adding external libraries on Windows.

Do I need to add them into my cygwin directory? Namely "/usr/local/lib"?

Am I able to have the .lib files in my project directory and add them that way?

If that is possible, can I possibly get some of the commands to use?

I have been trying link_directories and target_link_libraries, but no success so far. It says the linker can't find the libraries even though these libraries are in my project.

On the Linux side of things, do the libraries need to change to .so? I assume they will need to be of the .so format.

Any advice that can be offered would be greatly appreciated.

CMakeLists.txt:

 
cmake_minimum_required(VERSION 3.3)
project(SDL_Test)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

message(WARNING ${PROJECT_SOURCE_DIR})

link_directories(${PROJECT_SOURCE_DIR}/x64)

set(SOURCE_FILES main.cpp)
add_executable(SDL_Test ${SOURCE_FILES})
target_link_libraries(SDL_Test SDL2.lib SDL2main.lib)
6 comments
Comment actions Permalink
Hi Ryan!

CMake offers cross-platform to use third-party libraries via find_package command. For example, the way you link with SDL is described here: http://content.gpwiki.org/index.php/SDL:Tutorials:Setup#CMake . If you have them in the custom directory, you might need to add them to CMAKE_MODULE_PATH variable in order for find_package to work.
0
Comment actions Permalink

Okay I will try these suggestions, but it won't be until tonight. I will reply back again if they are successful.

Is it recommended to not use link_directories? Is using find_package and CMAKE_MODULE_PATH the recommended approach?

I just want to make sure I am using up to date practices.

0
Comment actions Permalink

Hi Ryan.

link_libraries and find_package complement each other.
(target_)link_libraries is the preferred way to tell the compiler to link with some libraries (it is better that passing compiler flags directly because it handles different compilers automatically).
find_packages is used to find the location of the libraries to link with (and pass them to link_libraries). It uses library-specific scripts to find the locations of all the required libraries and header files used by the library respecting current OS, environment and project settings.

So the common pattern is the following:

find_package(SDL2 REQUIRED) # this generates library-specific CMake variables for its include and lib paths
include_directories(... ${SDL2_INCLUDE_DIR})
target_link_libraries(target .. ${SDL2_LIBRARY})

Unfortunately there is no bundled FindSDL2.cmake script in default CMake distribution, so you need to download it from https://github.com/tcbrindle/sdl2-cmake-scripts and place it inside CMAKE_MODULE_PATH (see readme there; also please note that you should set SDL2_PATH beforehand on Windows where you don’t have system-wide library location).

Of course you can just provide required paths for target_link_library manually (or using some hand-written cmake code in your CMakeLists.txt), but it probably would be less cross-platform and reliable than the standard way and is considered the bad practice.

Hope this help!
0
Comment actions Permalink

Okay. Thank you for all of your help! I will try out your suggestion for SDL2.

0
Comment actions Permalink

I'm having a similar issue here.  The problem has nothing to do with finding the library, I already have pre-compiled .dll, .lib, .exp, and .pdb files and I know where they are.  I'm just having trouble getting them to link.

For example, here's my CMakeLists.txt for my simple project.  I want to simply compile a test using zmq:


cmake_minimum_required(VERSION 3.3)
project(Test)

#set(CMAKE_VERBOSE_MAKEFILE ON)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES main.cpp)
add_executable(Test ${SOURCE_FILES})

include_directories(c:/workspace/zmq-3.2.4/include)

target_link_libraries(Test c:/workspace/zmq-3.2.4/libzmq.lib)


I have the following in c:\workspace\zmq-3.2.4

libzmq.dll
libzmq.exp
libzmq.lib
libzmq.pdb

I've tried without the full path and using link_directories() without success.  It's linking as if I didn't even put the target_link_libraries declaration in at all.

[ 50%] Linking CXX executable Test.exe
CMakeFiles\Test.dir/objects.a(main.cpp.obj):main.cpp:(.text.startup+0x2c): undefined reference to `_imp__zmq_ctx_new'
CMakeFiles\Test.dir/objects.a(main.cpp.obj):main.cpp:(.text.startup+0x35): undefined reference to `_imp__zmq_ctx_destroy'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\Test.dir\build.make:96: recipe for target 'Test.exe' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/Test.dir/all' failed
makefile:82: recipe for target 'all' failed

Anyone else get this to work?

0
Comment actions Permalink

Found the problem.  It was my stupidity.

When I installed mingw-64, I didn't choose x86_64 as the architecture and used the default i686 (I'd love to know why mingw-64's default is not 64-bit!), so my compiler was generating 32-bit code and obviously failing to link to a 64-bit .lib. :)

0

Please sign in to leave a comment.