none
VS2013 でリンカ― エラー LNK2019 が発生します RRS feed

  • 質問

  • cpp-netlib を使用するコードをビルドする際に、"LNK2019" エラーが発生します。

    ただし、「http-get-cmd <uri>」という、<uri>の示すものを HTTP GET する、使用環境上の再頒布可能パッケージのインストールに依存しない Win32 コンソール アプリケーションを作成することが目的なので、cpp-netlib を使用せず簡単に実装できるのであれば、むしろそちらの方法を教えて頂けると有り難いです。

    http-get-cmd.obj : error LNK2019: unresolved external symbol  "bool __cdecl boost::network::uri::detail::parse(class std::_String_const_iterator<class std::_String_val<struct std::_Simple_types<char> > >,class std::_String_const_iterator<class std::_String_val<struct std::_Simple_types<char> > >,struct boost::network::uri::detail::uri_parts<class std::_String_const_iterator<class std::_String_val<struct std::_Simple_types<char> > > > &)" (?parse@detail@uri@network@boost@@YA_NV?$_String_const_iterator@V?$_String_val@U?$_Simple_types@D@std@@@std@@@std@@0AAU?$uri_parts@V?$_String_const_iterator@V?$_String_val@U?$_Simple_types@D@std@@@std@@@std@@@1234@@Z) referenced in function "private: void __thiscall boost::network::uri::uri::parse(void)" (?parse@uri@1network@boost@@AAEXXZ)
    http-get-cmd.obj : error LNK2019: unresolved external symbol  "public: __thiscall boost::network::http::impl::normal_delegate::normal_delegate(class boost::asio::io_service &)" (??0normal_delegate@impl@http@network@boost@@QAE@AAVio_service@asio@4@@Z) referenced in function "public: static class boost::shared_ptr<struct boost::network::http::impl::connection_delegate> __cdecl boost::network::http::impl::connection_delegate_factory<struct boost::network::http::tags::http_async_8bit_udp_resolve>::new_connection_delegate(class boost::asio::io_service &,bool,bool,class boost::optional<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class boost::optional<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class boost::optional<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class boost::optional<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >)" (?new_connection_delegate@?$connection_delegate_factory@Uhttp_async_8bit_udp_resolve@tags@http@network@boost@@@impl@http@network@boost@@SA?AV?$shared_ptr@Uconnection_delegate@impl@http@network@boost@@@5@AAVio_service@asio@5@_N1V?$optional@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@5@222@Z)

    開発環境は以下の通りです。

    • Windows 8.1 64 bit (version 6.3 build 9600) (ja-JP)
    • Microsoft Visual Studio Express 2013 for Windows Desktop (version 12.0.30723.00 Update 3) (ja-JP)

    私が作成したコードは以下の通りです。

    #include "stdafx.h"
    #include <boost/range/algorithm/for_each.hpp>
    #include <boost/network/protocol/http/client.hpp>
    #include <boost/network/uri/uri.hpp>
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        // create request
        boost::network::http::client::request request("http://www.boost.org/");
        request << boost::network::header("Connection", "close");
        
        // connect with GET
        boost::network::http::client client;
        boost::network::http::client::response response = client.get(request);
        
        // write response headers
        typedef boost::network::headers_range<boost::network::http::client::response>::type response_headers;
        boost::for_each(
            headers(response),
            [](const response_headers::value_type& value)->void
        {
            std::cout << value.first << ": " << value.second << std::endl;
        });
        
        // write response body
        std::cout << "\n---Body---\n" << body(response) << std::endl;
        
        return 0;
    }

    cpp-netlib のコンパイルは以下のように実施しました。

    -----------------------------------------------------------------

    【各種ツール】
    ActivePerl-5.20.2.2001-MSWin32-x64-298913.msi
    http://www.activestate.com/

    nasm-2.11.08-installer.exe
    http://www.nasm.us/

    cmake-3.2.2-win32-x86.exe
    http://www.cmake.org/

    【ソース コードなど】
    cpp-netlib-0.11.1-final.zip
    http://cpp-netlib.org/

    boost_1_58_0.zip
    http://www.boost.org/

    openssl-1.0.2a.tar.gz
    https://www.openssl.org/

    pthreads-w32-2-9-1-release.zip
    http://sourceforge.net/projects/pthreads4w/

    【各種フォルダー】
    …\temp
     ├boost_1_58_0
     ├cpp-netlib-0.11.1-final
     └openssl-1.0.2a

    …\cpp-libs
     ├boost
     │├include
     │└lib
     └openssl
      ├include
      └lib

    ----------------------------------------------------------------

    【1】各種ツールをインストールする。

    【2】ソース コードを temp フォルダー以下に解凍する。

    【3】環境変数を設定する。
    [変数名]“OPENSSL_ROOT_DIR”
    [変数値]“(cpp-libs フォルダーのフル パス)\openssl”

    [変数名]“OPENSSL_LIBRARIES”
    [変数値]“%OPENSSL_ROOT_DIR%\lib”

    [変数名]“OPENSSL_INCLUDE_DIR”
    [変数値]“%OPENSSL_ROOT_DIR%\include”

    [変数名]“BOOST_ROOT”
    [変数値]“(cpp-libs フォルダーのフル パス)\boost”

    [変数名]“BOOST_INCLUDEDIR”
    [変数値]“%BOOST_ROOT%\include”


    【4】[VS2013 x86 Native Tools コマンド プロンプト]を起動

    【5】コマンドが使えることを確認する。
    perl -v
    nasm -v
    cmake /V

    【6】環境変数が設定されていることを確認する。
    dir %OPENSSL_ROOT_DIR%
    dir %OPENSSL_LIBRARIES%
    dir %OPENSSL_INCLUDE_DIR%
    dir %BOOST_ROOT%
    dir %BOOST_INCLUDEDIR%

    【7】pthreads-win32 のファイルを以下に移動する。
    pthread.h
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include

    pthreadV*.lib
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib

    pthreadV*.dll
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin


    【8】C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib フォルダの pthreadVCE.lib ファイルを、pthreads.lib として同じフォルダにコピーする。

    ----------------------------------------------------------------

    【1】カレント ディレクトリを OpenSSL のソース コード解凍先フォルダーにする。
    cd /d (temp フォルダーのフルパス)\openssl-1.0.2a

    【2】configure。
    perl Configure VC-WIN32

    【3】ms\nt.mak ファイル生成。
    ms\do_nasm

    【4】make。
    nmake -f ms\nt.mak

    【5】make install。
    nmake -f ms\nt.mak install

    【6】(カレント ドライブ):\usr\local\ssl\lib" にある .lib ファイルを cpp-libs フォルダーの下の openssl\lib フォルダーに移動する。
    (カレント ドライブ):\usr\local\ssl\include" 以下を cpp-libs フォルダーの下の openssl\include フォルダーに移動する。

    【7】(カレント ドライブ):\usr フォルダーを削除したい場合は削除する。

    ----------------------------------------------------------------

    【1】カレント ディレクトリを boost のソース コード解凍先フォルダーにする。
    cd /d (temp フォルダーのフルパス)\boost_1_58_0

    【2】bootstrap.bat 実行。
    bootstrap.bat

    【3】ビルド。
    b2.exe link=static runtime-link=static

    【4】temp フォルダー の下の boost_1_58_0\stage\lib フォルダー以下を、cpp-libs フォルダーの下の boost\lib フォルダーに移動する。
    temp フォルダー の下の boost_1_58_0\boost フォルダーを、cpp-libs フォルダーの下の boost\include フォルダーにコピーする。

    ----------------------------------------------------------------

    【1】カレント ディレクトリを cpp-netlib のソース コード解凍先フォルダーにする。
    cd /d (temp フォルダーのフルパス)\cpp-netlib-0.11.1-final

    【2】cmake。
    cmake -DCMAKE_BUILD_TYPE=Debug

    【3】temp フォルダー の下の cpp-netlib-0.11.1-final フォルダーにある CPP-NETLIB.sln をダブル クリックする。

    【4】以下の 3 つのプロジェクトをビルド。
    ・cppnetlib-client-connections
    ・cppnetlib-server-parsers
    ・cppnetlib-uri

    【5】temp フォルダー の下の cpp-netlib-0.11.1-final\boost フォルダーにあるファイルを、cpp-libs フォルダーの下の boost\include\boost フォルダーに移動する。
    temp フォルダー の下の cpp-netlib-0.11.1-final\libs\network\src\Debug フォルダーにあるファイルおよびフォルダーを、cpp-libs フォルダーの下の boost\lib フォルダーにコピーする。

    2015年5月22日 6:37

すべての返信

  • 肝心な質問が書かれていないのですが…

        Visual C++でのリンクライブラリの指定方法がわからない

    のでしょうか?それとも、

        リンクライブラリを指定しているけどLNK2019(シンボル未解決)エラーになる理由がわからない

    のでしょうか?

    <boost/network/uri/uri.hpp>を使う時は、ヘッダーファイルのインクルードだけではなく、ライブラリのリンクが要るようですが。

    2015年5月22日 15:57
  • 申し訳ありません。外部のライブラリを使用するのが初めてなので、いずれに該当するかが判断できません。

    プロジェクトのプロパティで、変更した部分をお知らせいたします。

    VC++ ディレクトリ : インクルード ディレクトリ
    C:\Users\username\Documents\cpp-libs\boost\include;$(IncludePath)

    VC++ ディレクトリ : ライブラリ ディレクトリ
    C:\Users\username\Documents\cpp-libs\boost\lib;$(LibraryPath)

    C/C++ > コード生成 : ランタイム ライブラリ
    マルチスレッド デバッグ (/MTd)

    • 編集済み DJ_Kaosun 2015年5月22日 23:27
    2015年5月22日 23:16
  • cpp-netlibは自動でリンクライブラリを指定するようにはなっていないようので、cpp-netlibをビルドしてできたライブラリを

        リンカー > 入力 : 追加の依存ファイル

    に指定してください。

    2015年5月23日 0:29
  • リンカーの追加の依存ファイルとして、以下の 3 つのファイルを指定しました。
    C:\Users\username\Documents\cpp-libs\boost\lib\cppnetlib-client-connections.lib
    C:\Users\username\Documents\cpp-libs\boost\lib\cppnetlib-server-parsers.lib
    C:\Users\username\Documents\cpp-libs\boost\lib\cppnetlib-uri.lib

    LNK1104「ファイル 'libboost_system-vc120-mt-gd-1_58.lib' を開くことができません。」が出るようになりました。libboost_system-vc120-mt-s-1_58.lib と libboost_system-vc120-mt-sgd-1_58.lib はあるのですが、確かにこのファイルはありません。boost ライブラリのコンパイルに失敗しているのでしょうか。

    加えて、大量の LNK2005「"~" (?_~) は既に ~ で定義されています。」が表示されるようになりました。リンカーの追加の依存ファイルに指定するファイルを間違えたのでしょうか。

    また、LNK2038「'RuntimeLibrary' の不一致が検出されました。値 'MDd_DynamicDebug' が MTd_StaticDebug の値 'http-get-cmd.obj' と一致しません。」も表示されるようになりました。cpp-netlib のコンパイル オプションの変更が必要なのでしょうか。


    • 編集済み DJ_Kaosun 2015年5月23日 1:54
    2015年5月23日 1:52
  • C/C++ランタイムライブラリの使用方法が統一されていません。

    /MD、/MT、/LD (ランタイム ライブラリの使用)
    https://msdn.microsoft.com/ja-jp/library/2kzt1wy3.aspx

    Boostライブラリとご自身のプログラムで、わざわざ静的なランタイムライブラリを使用するように指定していますが、これらはそうする必要があってそうしているのでしょうか?

    そうでないなら、動的なランタイムライブラリを使用するようにすれば、統一できるのではないでしょうか。

    (他のライブラリでのランタイムライブラリの使用方法がわかりませんが、一般的には動的なランタイムライブラリが使われるので)

    2015年5月23日 5:05
  • 作成しようとしている Win32 コンソール アプリケーションは .exe ファイル 1 個で動作させることを考えています。これを実現するためには /MT または /MTd の指定が必要との認識です。

    OpenSSL, boost, cpp-netlib の各ライブラリのコンパイル オプションで /MTd が指定されていることを再確認すべきでしょうか。また、pthread は自分でコンパイルしていないので、こちらも /MTd を確実に指定して自分でコンパイルした方が良いでしょうか。

    2015年5月23日 14:39