如何在 snapcraft 中从创建二进制文件 "part" 引用创建库的 "part" 文件?
How to reference library-creating "part" files from a binary-creating "part" in snapcraft?
我有一个 snap,它将创建一个由多个二进制文件共享的库(在同一个 snap 中)。构建支持此功能的 snap 部件的最佳方式是什么?
以下是我的起点。
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?
好的,这是可以做到的,但考虑到工具的当前状态,它还没有达到应有的水平。截至本 post 日期需要考虑的几件事:
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
CMakeLists.txt for libwhatever(你可以看到尊重-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 for each binary就能成功找到libwhatever:
pkg_check_modules(ALL REQUIRED libwhatever gstreamer-video-1.0 gstreamer-app-1.0)
我有一个 snap,它将创建一个由多个二进制文件共享的库(在同一个 snap 中)。构建支持此功能的 snap 部件的最佳方式是什么?
以下是我的起点。
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?
好的,这是可以做到的,但考虑到工具的当前状态,它还没有达到应有的水平。截至本 post 日期需要考虑的几件事:
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
CMakeLists.txt for libwhatever(你可以看到尊重-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 for each binary就能成功找到libwhatever:
pkg_check_modules(ALL REQUIRED libwhatever gstreamer-video-1.0 gstreamer-app-1.0)