将本地JSONCpp安装与CMake和ExternalProject_Add链接

时间:2016-07-22 22:07:27

标签: c++ cmake jsoncpp

我试图使用CMake构建一个使用JSONCpp的项目。我想下载JSONCpp,在本地编译并链接到它。项目结构在单独的位置具有第三方目录的CMake文件。我收到两个错误。

  1. CMake进程尝试全局安装文件,我无法识别CMake变量以设置为在本地安装或根本不安装。
  2. 当我运行make时,链接器找不到libjsoncpp,即使我试图将所有变量设置为指向正确的方向。
  3. 有谁知道如何关闭全局安装的尝试?如何以可移植的方式将链接器指向正确的位置?

    我使用的项目结构是:

    ./jsoncpp_build_test.cc
    ./third_party/CMakeLists.txt.jsoncpp
    ./third_party/CMakeLists.txt
    ./CMakeLists.txt
    

    源文件jsoncpp_build_test是:

    #include <iostream>
    #include "json/json.h"
    int main(int argc, char **argv) {
      Json::Value json_doc;
      std::cout << json_doc.asString() << std::endl;
      return 0;
    }
    

    ./CMakeLists.txt文件。

    project(jsontest CXX C)
    cmake_minimum_required(VERSION 2.8.12)
    
    add_subdirectory(third_party)
    set(jsoncpp_lib_dir ${CMAKE_BINARY_DIR}/jsoncpp-build/src/lib_json)
    set(jsoncpp_src_dir ${CMAKE_BINARY_DIR}/jsoncpp-src/include)
    add_executable(jsoncpp_build_test "jsoncpp_build_test.cc")
    target_include_directories(jsoncpp_build_test PRIVATE  ${jsoncpp_src_dir})
    target_include_directories(jsoncpp_build_test PRIVATE ${jsoncpp_lib_dir})
    target_link_libraries(jsoncpp_build_test jsoncpp)
    

    third_party/CMakeLists.txt文件。我试图下载JSONCpp并安装它以避免用户必须运行多个与构建相关的命令。

    configure_file(CMakeLists.txt.jsoncpp
        jsoncpp/CMakeLists.txt)
    set(jsoncpp_work_dir "${CMAKE_BINARY_DIR}/third_party/jsoncpp")
    set(jsoncpp_build_dir "${CMAKE_BINARY_DIR}/jsoncpp-build")
    set(jsoncpp_lib_dir "${CMAKE_BINARY_DIR}/jsoncpp-lib")
    execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
        WORKING_DIRECTORY ${jsoncpp_work_dir} )
    message(STATUS "INSTALL DIR is ${CMAKE_INSTALL_PREFIX}")
    set(CMAKE_INSTALL_COMPONENT "${CMAKE_BINARY_DIR}/jsoncpp-lib")
    message(STATUS "INSTALL COMPONENT is ${CMAKE_INSTALL_COMPONENT}")
    execute_process(COMMAND ${CMAKE_COMMAND} --build .
        WORKING_DIRECTORY ${jsoncpp_work_dir} )
    

    最后,使用ExternalProject_Add模块的third_party/CMakeLists.txt.json文件。

    cmake_minimum_required(VERSION 2.8.12)
    project(jsoncpp-download NONE)
    set(jsoncpp_install_prefix "${CMAKE_BINARY_DIR}/jsoncpp-lib")
    set(CMAKE_INSTALL_COMPONENT "${jsoncpp_install_prefix}")
    include(ExternalProject)
    ExternalProject_Add(jsoncpp-parser
      GIT_REPOSITORY    https://github.com/open-source-parsers/jsoncpp.git
      GIT_TAG           master
      SOURCE_DIR        "${CMAKE_BINARY_DIR}/jsoncpp-src"
      BINARY_DIR        "${CMAKE_BINARY_DIR}/jsoncpp-build"
      INSTALL_DIR       "${CMAKE_BINARY_DIR}/jsoncpp-lib"
      CMAKE_ARGS        "-DCMAKE_INSTALL_PREFIX=${jsoncpp_install_prefix}"
    )
    

    cd build && cmake ../的结果如下。我不想在全球范围内安装jsoncpp。

    -- The CXX compiler identification is GNU 4.8.4
    -- The C compiler identification is GNU 4.8.4
    ...
    [100%] Built target jsoncpp_test
    [ 87%] Performing install step for 'jsoncpp-parser'
    [ 50%] Built target jsoncpp_lib_static
    [ 66%] Built target jsontestrunner_exe
    [100%] Built target jsoncpp_test
    Install the project...
    -- Install configuration: "Release"
    CMake Error at cmake_install.cmake:44 (FILE):
      file cannot create directory: /lib/pkgconfig.  Maybe need administrative privileges.
    make[3]: *** [install] Error 1
    make[2]: *** [jsoncpp-parser-prefix/src/jsoncpp-parser-stamp/jsoncpp-parser-install] Error 2
    make[1]: *** [CMakeFiles/jsoncpp-parser.dir/all] Error 2
    make: *** [all] Error 2
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /tmp/cmake_test/build
    

    make的结果是:

    Scanning dependencies of target jsoncpp_build_test
    [100%] Building CXX object
    CMakeFiles/jsoncpp_build_test.dir/jsoncpp_build_test.cc.o
    Linking CXX executable jsoncpp_build_test
    /usr/bin/ld: cannot find -ljsoncpp
    collect2: error: ld returned 1 exit status
    make[2]: *** [jsoncpp_build_test] Error 1
    make[1]: *** [CMakeFiles/jsoncpp_build_test.dir/all] Error 2
    make: *** [all] Error 2
    

1 个答案:

答案 0 :(得分:1)

默认情况下,命令configure_file所有出现的${var_name}替换为对应变量的值。

所以它用空字符串替换${jsoncpp_install_prefix},因为调用者的上下文中没有 jsoncpp_install_prefix 变量

如果您只想替换某些变量的引用,可以使用该命令的@ONLY选项,这样只会替换@var_name@次出现,但${var_name}仍将保留不变:

<强> THIRD_PARTY / CMakeLists.txt.json

cmake_minimum_required(VERSION 2.8.12)
project(jsoncpp-download NONE)
# This reference will be replaced when configured
set(jsoncpp_install_prefix "@CMAKE_BINARY_DIR@/jsoncpp-lib") 
# But this reference remains unchanged, until resulted CMakeLists.txt will be interpreted.
set(CMAKE_INSTALL_COMPONENT "${jsoncpp_install_prefix}")
...

<强> THIRD_PARTY /的CMakeLists.txt

configure_file(CMakeLists.txt.json
    jsoncpp/CMakeLists.txt
    @ONLY)