简体   繁体   中英

Hitting a LNK2019 error trying to link Boost with CMake

I am making my first project that is using CMake for the build system. I also decided this would be a good time to try to incorporate boost into my c++ skills. I've read through the documentation and flipped through SO and other sites, but I'm getting stuck on an LNK2019 error. I read here that this could be due to a 32/64 bit project / boost library mismatch. However, I am reasonably confident I build the right libraries. I'll post the relevant cmake, code, errors, and commands below

Build Command

b2.exe -a variant=debug,release link=shared,static threading=multi address-model=64

Generate Project Command

cmake .. -G"Visual Studio 12 Win64"

CMake File

cmake_minimum_required (VERSION 2.6)
project (Thoth)

add_definitions( -DBOOST_ALL_NO_LIB )
set(Boost_USE_STATIC_LIBS OFF )
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

configure_file (
  "${PROJECT_SOURCE_DIR}/main.h.in"
  "${PROJECT_BINARY_DIR}/main.h"
  )

set(BOOST_ROOT D:/Programs/boost_1_58_0)
set(BOOST_INCLUDEDIR ${BOOST_ROOT})
set(BOOST_LIBRARYDIR ${BOOST_ROOT}/stage/lib/)
find_package(Boost 1.58.0 COMPONENTS system filesystem REQUIRED)

include_directories("${PROJECT_BINARY_DIR}")

add_executable(Thoth main.cpp)

include_directories(${BOOST_INCLUDEDIR})
link_directories(${BOOST_LIBRARYDIR})

target_link_libraries( Thoth $(Boost_LIBRARIES))

C++ File

#define BOOST_LIB_DIAGNOSTIC

#include <iostream>
#include <fstream>
#include <string>
#include <boost/filesystem.hpp>

#include "main.h"

using namespace std;

int main(int argc, char *argv[]){
    string line;
    ifstream input("../images/source/balls2.nff", ios::in);
    if (!input){
        cout << "Unable to open file";
        exit(1);
    }
    else{
        while (getline(input, line)){
            cout << line << '\n';
        }

        input.close();
    }

    return 0;
}

Visual Studio Output

------ Build started: Project: ZERO_CHECK, Configuration: Debug x64 ------
------ Build started: Project: Thoth, Configuration: Debug x64 ------
main.obj : error LNK2019: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::system_category(void)" (?system_category@system@boost@@YAAEBVerror_category@12@XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'native_ecat''(void)" (??__Enative_ecat@system@boost@@YAXXZ)
main.obj : error LNK2019: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::generic_category(void)" (?generic_category@system@boost@@YAAEBVerror_category@12@XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'errno_ecat''(void)" (??__Eerrno_ecat@system@boost@@YAXXZ)
C:\Users\JR\Documents\Visual Studio 2013\Projects\thoth\_build64\Debug\Thoth.exe : fatal error LNK1120: 2 unresolved externals
------ Skipped Build: Project: ALL_BUILD, Configuration: Debug x64 ------
Project not selected to build for this solution configuration 
========== Build: 1 succeeded, 1 failed, 0 up-to-date, 1 skipped ==========

Hopefully I overlooked something stupid, but I've been reading through other people's answers and not getting anywhere for a little bit. I figured it was time to ask for some help.

After Feedback

I'll keep the most up to date CMake and debug output here. So that other users (or me) can compare the original and final code.

CMake

cmake_minimum_required (VERSION 2.6)
project (Thoth)

set(Boost_USE_STATIC_LIBS OFF )
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

configure_file (
  "${PROJECT_SOURCE_DIR}/main.h.in"
  "${PROJECT_BINARY_DIR}/main.h"
  )

set (Boost_DEBUG ON)
set(BOOST_ROOT D:/Programs/boost_1_58_0)
find_package(Boost 1.58.0 COMPONENTS system filesystem REQUIRED)
set(Boost_INCLUDE_DIRS ${BOOST_ROOT})
set(Boost_LIBRARY_DIRS ${BOOST_ROOT}/stage/lib/)
set(Boost_LIBRARIES ${BOOST_ROOT}/stage/lib/)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARIES})

include_directories("${PROJECT_BINARY_DIR}")

add_executable(Thoth main.cpp)

if (WIN32)
    add_definitions( -DBOOST_ALL_NO_LIB )
    add_definitions( -DBOOST_ALL_DYN_LINK )
endif()

target_link_libraries( Thoth $(Boost_LIBRARIES))

CMake Command Output With Debug On (Removed full path to FindBoost for readability)

cmake .. -G"Visual Studio 12 Win64"
-- [ FindBoost.cmake:513 ] _boost_TEST_VERSIONS =
-- [ FindBoost.cmake:515 ] Boost_USE_MULTITHREADED = ON
-- [ FindBoost.cmake:517 ] Boost_USE_STATIC_LIBS = OFF
-- [ FindBoost.cmake:519 ] Boost_USE_STATIC_RUNTIME = OFF
-- [ FindBoost.cmake:521 ] Boost_ADDITIONAL_VERSIONS =
-- [ FindBoost.cmake:523 ] Boost_NO_SYSTEM_PATHS =
-- [ FindBoost.cmake:575 ] Declared as CMake or Environmental Variables:
-- [ FindBoost.cmake:577 ]   BOOST_ROOT = D:/Programs/boost_1_58_0
-- [ FindBoost.cmake:579 ]   BOOST_INCLUDEDIR =
-- [ FindBoost.cmake:581 ]   BOOST_LIBRARYDIR =
-- [ FindBoost.cmake:583 ] _boost_TEST_VERSIONS =
-- [ FindBoost.cmake:652 ] Include debugging info:
-- [ FindBoost.cmake:654 ]   _boost_INCLUDE_SEARCH_DIRS =
D:/Programs/boost_1_58_0/include;D:/Programs/boost_1_58_0;PATHS;C:/boost/include;C:/boost;/sw/local/include
-- [ C:/Program Files (x86)/CMake/share/cmake-3.0/Modules/FindBoost.cmake:656 ]   _boost_PATH_SUFFIXES =
-- [ FindBoost.cmake:676 ] location of version.hpp: D:/Programs/boost_1_58_0/boost/version.hpp
-- [ FindBoost.cmake:700 ] version.hpp reveals boost 1.58.0
-- [ FindBoost.cmake:785 ] guessed _boost_COMPILER = -vc120
-- [ FindBoost.cmake:795 ] _boost_MULTITHREADED = -mt
-- [ FindBoost.cmake:838 ] _boost_RELEASE_ABI_TAG = -
-- [ FindBoost.cmake:840 ] _boost_DEBUG_ABI_TAG = -gd
-- [ FindBoost.cmake:888 ] _boost_LIBRARY_SEARCH_DIRS = D:/Programs/boost_1_58_0/lib;D:/Programs/boost_1_58_0/stage/lib;D:/Programs/boost_1_58_0/lib;D:/Programs/boost_1_58_0/../lib;D:/Programs/boost_1_58_0/stage/lib;PATHS;C:/boost/lib;C:/boost;/sw/local/lib
-- [ FindBoost.cmake:998 ] Searching for SYSTEM_LIBRARY_RELEASE: boost_system-vc120-mt-1_58;boost_system-vc120-mt;boost_system-mt-1_58;boost_system-mt;boost_system
-- [ FindBoost.cmake:1034 ] Searching for SYSTEM_LIBRARY_DEBUG: boost_system-vc120-mt-gd-1_58;boost_system-vc120-mt-gd;boost_system-mt-gd-1_58;boost_system-mt-gd;boost_system-mt;boost_system
-- [ FindBoost.cmake:998 ] Searching for FILESYSTEM_LIBRARY_RELEASE: boost_filesystem-vc120-mt-1_58;boost_filesystem-vc120-mt;boost_filesystem-mt-1_58;boost_filesystem-mt;boost_filesystem
-- [ FindBoost.cmake:1034 ] Searching for FILESYSTEM_LIBRARY_DEBUG: boost_filesystem-vc120-mt-gd-1_58;boost_filesystem-vc120-mt-gd;boost_filesystem-mt-gd-1_58;boost_filesystem-mt-gd;boost_filesystem-mt;boost_filesystem
-- [ FindBoost.cmake:1085 ] Boost_FOUND = 1
-- Boost version: 1.58.0
-- Found the following Boost libraries:
  --   system
  --   filesystem
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/JR/Documents/Visual Studio 2013/Projects/thoth/_build64

There are two fairly trivial issues here which should hopefully be easy to fix.

The first is that find_package(Boost ...) is probably doing its job correctly, ie it's setting good values for Boost_INCLUDE_DIRS , Boost_LIBRARY_DIRS and Boost_LIBRARIES . However, you immediately overwrite these variables by calling the three set commands! So you should remove those three commands.

The other issue is in your target_link_libraries call - you've accidentally used parentheses rather than braces when trying to dereference Boost_LIBRARIES - ie change $(Boost_LIBRARIES) to ${Boost_LIBRARIES} .


By the way, there are a couple of other points which are unrelated to the issue:

  1. You shouldn't generally set BOOST_ROOT like that inside the CMakeLists.txt. It's really meant to be set by passing it as a -D arg on the command line (or via the CMake GUI) so that it's not hard-coded to a value specific to your own individual machine.

  2. You don't need the link_directories call. Its own documentation discourages its use:

    Note that this command is rarely necessary. Library locations returned by find_package() and find_library() are absolute paths. Pass these absolute library file paths directly to the target_link_libraries() command. CMake will ensure the linker finds them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM