Hello, I am trying to package my CMake Qt application into a snap package.
I am trying to build a part called “sc-gui” with the following configuration:
name: sc-gui
version: '1.0'
base: core20
confinement: strict
grade: devel
parts:
sc-gui:
plugin: cmake
source: .
build-snaps:
- kde-frameworks-5-qt-5-15-core20-sdk
- lxi-tools
build-packages: [pkg-config, build-essential, binutils-dev, libssl-dev, libgl-dev]
cmake-parameters:
- -DADDITIONAL_INCLUDES=/snap/lxi-tools/current/usr/include/${SNAPCRAFT_ARCH_TRIPLET}/qt5/QtCharts
- -DQT5PATH:PATH=/snap/kde-frameworks-5-qt-5-15-core20-sdk/current/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/qt5
- -DCMAKE_PREFIX_PATH=/snap/kde-frameworks-5-qt-5-15-core20-sdk/current/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/cmake
- -DQt5Widgets_DIR:PATH=/snap/kde-frameworks-5-qt-5-15-core20-sdk/current/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/cmake/Qt5Widgets
- -DQt5Charts_DIR:PATH=/snap/lxi-tools/current/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/cmake/Qt5Charts
stage-packages:
- gstreamer1.0-plugins-bad
- fonts-ubuntu
- qml-module-qtcharts
stage-snaps:
- kde-frameworks-5-qt-5-15-core20
- lxi-tools
Now, without “stage-packages” part the app builds fine - it correctly recognizes gcc compiler from build-essential package install in multipass image and proceeds with the build.
The problem appears when I add “stage-packages” to the part and results in cmake not being able to correctly identify the compiler, failing with the following error:
-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- broken
CMake Error at /usr/share/cmake-3.16/Modules/CMakeTestCCompiler.cmake:60 (message):
The C compiler
"/usr/bin/cc"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: /root/parts/sc-gui/build/CMakeFiles/CMakeTmp
Run Build Command(s):/root/parts/sc-gui/install/usr/bin/make cmTC_99ce7/fast && /root/parts/sc-gui/install/usr/bin/make -f CMakeFiles/cmTC_99ce7.dir/build.make CMakeFiles/cmTC_99ce7.dir/build
make[1]: Entering directory '/root/parts/sc-gui/build/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_99ce7.dir/testCCompiler.c.o
/usr/bin/cc -isystem/root/parts/sc-gui/install/usr/include -isystem/root/parts/sc-gui/install/usr/include/x86_64-linux-gnu -o CMakeFiles/cmTC_99ce7.dir/testCCompiler.c.o -c /root/parts/sc-gui/build/CMakeFiles/CMakeTmp/testCCompiler.c
as: error while loading shared libraries: libopcodes-2.26.1-system.so: cannot open shared object file: No such file or directory
CMakeFiles/cmTC_99ce7.dir/build.make:65: recipe for target 'CMakeFiles/cmTC_99ce7.dir/testCCompiler.c.o' failed
make[1]: *** [CMakeFiles/cmTC_99ce7.dir/testCCompiler.c.o] Error 1
make[1]: Leaving directory '/root/parts/sc-gui/build/CMakeFiles/CMakeTmp'
Makefile:121: recipe for target 'cmTC_99ce7/fast' failed
make: *** [cmTC_99ce7/fast] Error 2
I spend quite a while researching the problem, and here is what I have found so far. It appears that the cmake plugin generates build script ‘/root/parts/sc-gui/run/build.sh’ with the following content:
#!/bin/bash
set -e
# Environment
## Part Environment
export SNAPCRAFT_ARCH_TRIPLET="x86_64-linux-gnu"
export SNAPCRAFT_EXTENSIONS_DIR="/snap/snapcraft/6751/share/snapcraft/extensions"
export SNAPCRAFT_PARALLEL_BUILD_COUNT="2"
export SNAPCRAFT_PRIME="/root/prime"
export SNAPCRAFT_PROJECT_NAME="sc-gui"
export SNAPCRAFT_PROJECT_VERSION="1.0"
export SNAPCRAFT_PROJECT_DIR="/root/project"
export SNAPCRAFT_PROJECT_GRADE="devel"
export SNAPCRAFT_STAGE="/root/stage"
export SNAPCRAFT_TARGET_ARCH="amd64"
export SNAPCRAFT_PART_SRC="/root/parts/sc-gui/src"
export SNAPCRAFT_PART_SRC_WORK="/root/parts/sc-gui/src/"
export SNAPCRAFT_PART_BUILD="/root/parts/sc-gui/build"
export SNAPCRAFT_PART_BUILD_WORK="/root/parts/sc-gui/build"
export SNAPCRAFT_PART_INSTALL="/root/parts/sc-gui/install"
export PATH="/root/parts/sc-gui/install/usr/sbin:/root/parts/sc-gui/install/usr/bin:/root/parts/sc-gui/install/sbin:/root/parts/sc-gui/install/bin:$PATH"
export CPPFLAGS="-isystem/root/parts/sc-gui/install/usr/include -isystem/root/parts/sc-gui/install/usr/include/x86_64-linux-gnu"
export CFLAGS="-isystem/root/parts/sc-gui/install/usr/include -isystem/root/parts/sc-gui/install/usr/include/x86_64-linux-gnu"
export CXXFLAGS="-isystem/root/parts/sc-gui/install/usr/include -isystem/root/parts/sc-gui/install/usr/include/x86_64-linux-gnu"
export LDFLAGS="-L/root/parts/sc-gui/install/lib -L/root/parts/sc-gui/install/usr/lib -L/root/parts/sc-gui/install/lib/x86_64-linux-gnu -L/root/parts/sc-gui/install/usr/lib/x86_64-linux-gnu"
## Plugin Environment
export CMAKE_PREFIX_PATH="${SNAPCRAFT_STAGE}"
export SNAPCRAFT_CMAKE_ARGS=""
## User Environment
set -xeuo pipefail
cmake "${SNAPCRAFT_PART_SRC_WORK}" -G "Unix Makefiles" ${SNAPCRAFT_CMAKE_ARGS} -DADDITIONAL_INCLUDES=/snap/lxi-tools/current/usr/include/x86_64-linux-gnu/qt5/QtCharts -DQT5PATH:PATH=/snap/kde-frameworks-5-qt-5-15-core20-sdk/current/usr/lib/x86_64-linux-gnu/qt5 -DCMAKE_PREFIX_PATH=/snap/kde-frameworks-5-qt-5-15-core20-sdk/current/usr/lib/x86_64-linux-gnu/cmake -DQt5Widgets_DIR:PATH=/snap/kde-frameworks-5-qt-5-15-core20-sdk/current/usr/lib/x86_64-linux-gnu/cmake/Qt5Widgets -DQt5Charts_DIR:PATH=/snap/lxi-tools/current/usr/lib/x86_64-linux-gnu/cmake/Qt5Charts
cmake --build . -- -j"${SNAPCRAFT_PARALLEL_BUILD_COUNT}"
DESTDIR="${SNAPCRAFT_PART_INSTALL}" cmake --build . --target install
Now the problem is the lines with PATH, CPPFLAGS, CFLAGS, CXXFLAGS, and LDFLAGS. It seems as the purpose of those is to guide the build process such that the packages added with “stage-packages” (that are install into /root/parts/<part name>/install) are also used during the build, but why would we need them at the build stage?
More than that, in my case somehow the /usr/bin/as utility (asm compiler?) gets installed with the packages (I am not sure how it gets with the “gstreamer1.0-plugins-bad”, “fonts-ubuntu” and “qml-module-qtcharts” packages, but nevertheless) to /root/parts/sc-gui/install/usr/bin folder, which is added to PATH by cmake plugin build script listed above. That utility is the one that is not linking and fails to find libopcodes-2.26-system.so:
snapcraft-sc-gui # ldd /root/parts/sc-gui/install/usr/bin/as
linux-vdso.so.1 (0x00007fffad330000)
libopcodes-2.26.1-system.so => not found
libbfd-2.26.1-system.so => not found
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f0c81a97000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0c818a5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0c81aba000)
whereas in the meantime the system one links ok:
snapcraft-sc-gui # ldd /usr/bin/as
linux-vdso.so.1 (0x00007ffe3f3ee000)
libopcodes-2.34-system.so => /usr/lib/x86_64-linux-gnu/libopcodes-2.34-system.so (0x00007f082a903000)
libbfd-2.34-system.so => /usr/lib/x86_64-linux-gnu/libbfd-2.34-system.so (0x00007f082a7bc000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f082a7a0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f082a5ae000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f082a5a8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f082ab18000)
Other variables, such as CPPFLAGS, CFLAGS, CXXFLAGS, and LDFLAGS also harmfully influence build process. For example, if I force to use proper /usr/bin/as utility by unsetting the PATH variable, the system includes are messed up by the flags variables (e.g. “…/usr/include/stdlib.h” is included instead of “…/usr/include/c++/9/stdlib.h”).
So, to summarize, I have following questions:
- Why cmake plugin sets PATH, CPPFLAGS, CFLAGS, CXXFLAGS variables? What is the goal of this?
- How to overcome the problem I have encountered? I am thinking about two options:
- redefine those variables using build-environment. But may I will break something in the future?
- Add those packages into snap with another “nil” parts, so they do not influence the build process?