【问题标题】:How to reference library-creating "part" files from a binary-creating "part" in snapcraft?如何从 snapcraft 中的二进制创建“部分”引用库创建“部分”文件?
【发布时间】:2018-12-08 18:06:41
【问题描述】:

我有一个快照,它将创建一个由多个二进制文件共享的库(在同一个快照内)。构建按扣部件以支持这一点的最佳方式是什么?

以下是我的出发点。

parts:
  libwhatever:
    plugin: cmake
    source: ...
    configflags: [
      ...
    ]
    build-packages:
      - liblog4cxx-dev
      - libboost-system-dev
      - libboost-filesystem-dev
      - libboost-thread-dev

  binwhatever:
    plugin: cmake
    source: binwhatever
    configflags: [
    ]
    build-packages:
      - liblog4cxx-dev
      - libboost-system-dev
      - libboost-filesystem-dev
      - libboost-test-dev
      - libboost-thread-dev
      - libgstreamer1.0-dev
      - #how can I reference libwhatever here?

【问题讨论】:

    标签: snapcraft


    【解决方案1】:

    好的,这是可以做到的,但考虑到工具的当前状态,它并不像它应该的那样光滑。截至本文发布之日,需要考虑的几件事:

    1) Snap cmake 插件不允许您在构建发生之前定义环境变量(snapcraftctl 在运行之前丢弃环境)——除非您完全覆盖它。所以下面的解决方案采取了不修改每个二进制文件的cmake环境的方式进行操作。

    2) 据我所知,snapcraft.yaml 确实没有办法知道“libwhatever”,因为它在构建开始时不存在。因此,snapcraft.yaml 中每个二进制文件对 libwhatever 的所有引用都将被删除。

    3) 要使以下解决方案起作用,“libwhatever”必须允许给出安装前缀。这允许我们将它编译到 /usr 而不是 /usr/local 或 /opt 或任何地方,并且在构建二进制文件时会找到“libwhatever”。

    snapcraft.yaml:

    name: project-whatever
    version: "6.0.0" 
    summary: ""
    description: |
      show how to use a common libwhatever among one or more binaries 
      in a snap
    grade: devel
    confinement: devmode
    
    parts:
      libwhatever:
        plugin: cmake
        source: libwhatever
        configflags: [
          -DCMAKE_BUILD_TYPE=Debug,
          -DCMAKE_INSTALL_PREFIX=/usr
        ]
        build-packages:
          - liblog4cxx-dev
          - libboost-system-dev
          - libboost-filesystem-dev
          - libboost-test-dev
          - libboost-thread-dev
          - libgstreamer1.0-dev
          - libpthread-stubs0-dev
          - libglib2.0-dev
        stage-packages:
          - libc6
          - libgstreamer1.0-0
          - gstreamer1.0-plugins-base-apps
          - liblog4cxx10v5
          - libglib2.0-0
    
      binwhatever:
        after:
          - libwhatever
        plugin: cmake
        source: binwhatever
        configflags: [
          -DCMAKE_BUILD_TYPE=Debug,
          -DCMAKE_INSTALL_PREFIX=/opt/whatever
          ]
        build-packages:
          - liblog4cxx-dev
          - libboost-system-dev
          - libboost-filesystem-dev
          - libboost-test-dev
          - libboost-thread-dev
          - libboost-program-options-dev
          - libgstreamer1.0-dev
          - libgstreamer-plugins-base1.0-dev
        stage-packages:
          - libc6
          - libgstreamer1.0-0
          - gstreamer1.0-plugins-base-apps
          - liblog4cxx10v5
          - libboost-system1.65.1
          - libboost-filesystem1.65.1
          - libboost-thread1.65.1
          - libboost-program-options1.65.1
    

    用于 libwhatever 的 CMakeLists.txt(如您所见,尊重 -DCMAKE_INSTALL_PREFIX 给出的内容):

    cmake_minimum_required(VERSION 3.10)
    
    set(VERSION_MAJOR 1)
    set(VERSION_MINOR 2)
    set(VERSION_PATCH 0)
    
    project(whatever VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" DESCRIPTION "whatever")
    
    set(CMAKE_CXX_FLAGS "-std=gnu++11")
    
    include(FindPkgConfig)
    include(GNUInstallDirs)
    
    set(REQUIRED_LIBS gstreamer-1.0 liblog4cxx pthread-stubs glib-2.0)
    pkg_check_modules(ALL REQUIRED ${REQUIRED_LIBS})
    find_package(Boost REQUIRED COMPONENTS system filesystem regex thread)
    
    add_library(whatever-shared SHARED whatever.cpp)
    
    set_target_properties(whatever-shared PROPERTIES VERSION ${PROJECT_VERSION})
    set_target_properties(whatever-shared PROPERTIES SOVERSION ${VERSION_MAJOR})
    set_target_properties(whatever-shared PROPERTIES PUBLIC_HEADER whatever.h)
    
    target_include_directories(whatever-shared PUBLIC ${ALL_INCLUDE_DIRS} PUBLIC ${Boost_INCLUDE_DIRS})
    link_directories(whatever-shared PUBLIC ${ALL_LIBRARY_DIRS} PUBLIC ${Boost_LIBRARY_DIRS})
    target_link_libraries(whatever-shared ${ALL_LIBRARIES} ${Boost_LIBRARIES})
    
    function(JOIN OUTPUT GLUE)
      set(_TMP_RESULT "")
      set(_GLUE "") # effective glue is empty at the beginning
      foreach(arg ${ARGN})
        set(_TMP_RESULT "${_TMP_RESULT}${_GLUE}${arg}")
        set(_GLUE "${GLUE}")
      endforeach()
      set(${OUTPUT} "${_TMP_RESULT}" PARENT_SCOPE)
    endfunction()
    
    join(PKG_CONFIG_REQUIRED_LIBS_STR " " ${REQUIRED_LIBS})
    set(PKG_CONFIG_LDFLAGS)
    set(PKG_CONFIG_LDFLAGS_STR "-lboost_system -lboost_thread -lboost_regex -lboost_filesystem")
    configure_file(libwhatever.pc.in libwhatever.pc @ONLY)
    
    install(TARGETS whatever-shared
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
      PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
    
    install(FILES ${CMAKE_BINARY_DIR}/libwhatever.pc
      DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
    

    libwhatever.pc.in:

    prefix=@CMAKE_INSTALL_PREFIX@
    exec_prefix=@CMAKE_INSTALL_PREFIX@
    libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
    includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
    
    Name: @PROJECT_NAME@
    Description: @PROJECT_DESCRIPTION@
    Version: @PROJECT_VERSION@
    
    Requires: @PKG_CONFIG_REQUIRED_LIBS_STR@
    Libs: -L${libdir} -lwhatever @PKG_CONFIG_LDFLAGS_STR@
    Cflags: -I${includedir} @PKG_CONFIG_CFLAGS_STR@
    

    现在每个二进制文件的每个 CMakeLists.txt 都可以成功找到 libwhatever:

    pkg_check_modules(ALL REQUIRED libwhatever gstreamer-video-1.0 gstreamer-app-1.0)
    

    【讨论】:

    • 如果将来出现更好的方法,我很乐意接受这个答案。
    猜你喜欢
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 2021-05-09
    相关资源
    最近更新 更多