Cmake build error due to PATH, CPPFLAGS, CFLAGS and LDFLAGS environment variables

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:

  1. Why cmake plugin sets PATH, CPPFLAGS, CFLAGS, CXXFLAGS variables? What is the goal of this?
  2. 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?

Also, my host machine details are as follows:

user@pc:~/WorkDir/SC/scgui$ snap version
snap    2.51.3
snapd   2.51.3
series  16
ubuntu  20.04
kernel  5.4.0-77-generic
user@pc:~/WorkDir/SC/scgui$ snapcraft --version
snapcraft, version 5.0

The /usr/bin/as file comes from the lxi-tools snap that you’re staging. It’s worth mentioning that this particular snap is based on core (Ubuntu 16.04) and therefore the binaries included will be incompatible with your snap’s core20 base (Ubuntu 20.04).

That’s it! Thank you. Indeed, removing the “lxi-tools” snap (which I stupidly used to get QtCharts module) and using appropriate deb packages instead resolved the problem - no PATH conflicts any more.

To summarize, my current part looks something like this:

base: core20
confinement: strict
grade: devel

parts:
  sc-gui:
    plugin: cmake
    source: .
    build-snaps: [kde-frameworks-5-qt-5-15-core20-sdk]
    build-packages: [pkg-config, build-essential, binutils-dev, libssl-dev, libgl-dev, libqt5charts5-dev]
    cmake-parameters:
      - -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=/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/cmake/Qt5Charts
    stage-snaps:
      - kde-frameworks-5-qt-5-15-core20
    stage-packages:
      - gstreamer1.0-plugins-bad
      - fonts-ubuntu
      - libpulse0
      - libpulse-mainloop-glib0
      - libqt5charts5
      - qml-module-qtcharts