Failing compiling of C source file

Hi

I am trying to build a snap package for a software that uses autotools and is written in Common lisp with a sprinkling of C. :slight_smile:

The building of the snap package fails when “ASDF” (the equivalent of Make for lisp) try to build a library that is a wrapper of a C library (libjpegturbo). There is a phase where asdf compile a small C source (using gcc) file that acts as a low level “glue” with the C library.

The C compiler complains that can is unable to find the header “turbojpeg.h”, but the ‘configure’ script contains a test just for this header file and it passes.

I know that lisp is a niche language but maybe there is some other person who packaged a lisp program with snap and can provide some tips.

Any help is appreciated, if needed i can provide the snapcraft.yaml (still a draft, of course) and the failure log.

Thanks in advance. C.

Please include the log and snacpraft.yaml so that others can help you.

Hi!

Thanks for your reply, i have someway managed to fix the issue with the header file (even likely in a wrong way) but i stepped into another issue, below i have attached the YAML file with the error i get from the log.

Bye!
C.

name: tinmop 
base: core22 
version: '0.1' 
summary: Description 
description: |
  This is my-snap's description. You have a paragraph or two to tell the
  most important story about your snap. Keep it under 100 words though,
  we live in tweetspace and your description wants to look good in the snap
  store.
apps:
  tinmop:
    command: bin/tinmop
grade: devel 
confinement: devmode 
parts:
  my-part:
    # See 'snapcraft plugins'
    plugin: autotools
    source: "https://codeberg.org/cage/tinmop.git"
    source-type: "git"
    stage-packages:
      - sbcl
      - gettext
      - gettext-base
      - libgettextpo-dev
      - libgettextpo0
      - man-db
      - gpg
      - curl
      - openssl
      - gcc
      - git
      - tk
      - imagemagick
      - xdg-utils
      - unzip
      - file
      - libssl3
      - libssl-dev
      - libncursesw6
      - libncurses-dev
      - libsqlite3-0
      - libsqlite3-dev
      - libturbojpeg
      - libturbojpeg0-dev
      - libsdl2-dev
      - libsdl2-2.0-0
      - pkg-config
      - pkgconf
    override-build: |
      apt-get -y install libturbojpeg libturbojpeg0-dev libsdl2-dev libsdl2-2.0-0 libssl3 gettext
      ./configure
      bash quick_quicklisp.sh --do-not-prompt
      make
      make install

# Command '['snap', 'pack', '--filename', 'tinmop_0.1_amd64.snap', '--compression', 'xz', PosixPath('/root/prime'), PosixPath('/root/project')]' returned non-zero exit status 1.

you should remove that apt-get line and simply list these debs in build-packages:, that might perhaps already solve the issue you are seeing …

(and remove all these -dev packages from stage-packages: they will likely not be used at runtime of your snap and will just grow the snap size)

snap pack does some simple validation of the snap when packing it. The actual error is likely a bit above this line.

Thank you very much for your help, folks!

Following your suggestions i removed the call to apt-get install -y ... from override-build and switched from stage-packages: to build-packages, may i ask what is the difference between the last two?

name: tinmop # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
description: |
  This is my-snap's description. You have a paragraph or two to tell the
  most important story about your snap. Keep it under 100 words though,
  we live in tweetspace and your description wants to look good in the snap
  store.
apps:
  tinmop:
    command: bin/tinmop
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
parts:
  my-part:
    # See 'snapcraft plugins'
    plugin: autotools
    source: "https://codeberg.org/cage/tinmop.git"
    source-type: "git"
    build-packages:
      - sbcl
      - gettext
      - gettext-base
      - libgettextpo-dev
      - libgettextpo0
      - man-db
      - gpg
      - curl
      - openssl
      - gcc
      - git
      - tk
      - imagemagick
      - xdg-utils
      - unzip
      - file
      - libssl3
      - libssl-dev
      - libncursesw6
      - libncurses-dev
      - libsqlite3-0
      - libsqlite3-dev
      - libturbojpeg
      - libturbojpeg0-dev
      - libsdl2-dev
      - libsdl2-2.0-0
#      - pkg-config
      - pkgconf
    override-build: |
      ./configure --prefix=/usr/
      bash quick_quicklisp.sh --do-not-prompt
      make
      make install

Regarding the -dev library packages, they are needed because the lisp libraries that wrap the C libraries try to get information about typedef or struct from the header file and try to map them to lisp code (maybe i can safely remove the gettext related ones, though).

Anyway the compilation works fine but i still get an error, i attached what i believe are the relevant parts of the log below:

2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.813 ::  /usr/bin/mkdir -p '/usr/bin'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.816 ::  /usr/bin/install -c tinmop '/usr/bin'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.930 ::  /usr/bin/mkdir -p '/usr/etc/tinmop'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.933 ::  /usr/bin/install -c -m 644 etc/init.lisp etc/default-theme.conf etc/shared.conf etc/shared-gui.conf '/usr/etc/tinmop'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.936 ::  /usr/bin/mkdir -p '/usr/share/doc/tinmop'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.940 ::  /usr/bin/install -c -m 644 README.org LICENSES.org CONTRIBUTING.org doc/tinmop.org doc/send-toot.lisp NEWS.org ChangeLog AUTHORS '/usr/share/doc/tinmop'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.944 ::  /usr/bin/mkdir -p '/usr/share/man/man1'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.947 ::  /usr/bin/install -c -m 644 'doc/tinmop.man' '/usr/share/man/man1/tinmop.1'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.951 ::  /usr/bin/mkdir -p '/usr/share/tinmop'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.955 ::  /usr/bin/mkdir -p '/usr/share/tinmop/data/modules'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.955 ::  /usr/bin/install -c -m 644  data/modules/delete-by-regex.lisp data/modules/expand-abbrev-command-window.lisp data/modules/fetch-expired-poll.lisp data/modules/next-previous-open.lisp data/modules/rewrite-message-urls.lisp data/modules/share-gemini-link.lisp '/usr/share/tinmop/data/modules'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.965 ::  /usr/bin/mkdir -p '/usr/share/tinmop/data/error-pages'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.966 ::  /usr/bin/install -c -m 644  data/error-pages/51 data/error-pages/header-51.png '/usr/share/tinmop/data/error-pages'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.968 ::  /usr/bin/mkdir -p '/usr/share/tinmop/data/icons'
2024-04-17 16:02:38.495 :: 2024-04-17 16:02:28.968 ::  /usr/bin/install -c -m 644  data/icons/fmw_arrow-down.png data/icons/fmw_arrow-up.png data/icons/fmw_back.png data/icons/fmw_bullet-go.

[...]

2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.173 Staging my-part
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.214 execute action my-part:Action(part_name='my-part', step=Step.STAGE, action_type=ActionType.RUN, reason=None, project_vars=None, properties=ActionProperties(changed_files=None, changed_dirs=None))
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.234 Priming my-part
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.234 execute action my-part:Action(part_name='my-part', step=Step.PRIME, action_type=ActionType.RUN, reason=None, project_vars=None, properties=ActionProperties(changed_files=None, changed_dirs=None))
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.253 patch_elf: not enabled for part 'my-part'
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.257 Extracting and updating metadata...
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.277 Copying snap assets...
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.280 finalize icon: None
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.281 relative icon path: None
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.281 Generating snap metadata...
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.304 Generated snap metadata
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.307 Reading snap metadata...
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.312 Running linters...
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.314 Running linter: classic
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.332 Running linter: library
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.389 pack_snap: output=None, compression='xz'
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.389 pack_snap: check skeleton
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.431 Creating snap package...
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.432 Pack command: ['snap', 'pack', '--filename', 'tinmop_0.1_amd64.snap', '--compression', 'xz', PosixPath('/root/prime'), PosixPath('/root/project')]
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.442 Command '['snap', 'pack', '--filename', 'tinmop_0.1_amd64.snap', '--compression', 'xz', PosixPath('/root/prime'), PosixPath('/root/project')]' returned non-zero exit status 1.
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.443 Detailed information: 2024/04/17 16:02:30.438442 container.go:215: in snap "tinmop": path "bin" does not exist
2024-04-17 16:02:38.496 :: 2024/04/17 16:02:30.438505 container.go:215: in snap "tinmop": path "bin/tinmop" does not exist
2024-04-17 16:02:38.496 :: error: cannot pack "/root/prime": snap is unusable due to missing files
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.447 Traceback (most recent call last):
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.447   File "/snap/snapcraft/11040/lib/python3.10/site-packages/snapcraft/pack.py", line 137, in pack_snap
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.447     proc = subprocess.run(
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.447   File "/snap/snapcraft/11040/usr/lib/python3.10/subprocess.py", line 526, in run
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.447     raise CalledProcessError(retcode, process.args,
2024-04-17 16:02:38.496 :: 2024-04-17 16:02:30.447 subprocess.CalledProcessError: Command '['snap', 'pack', '--filename', 'tinmop_0.1_amd64.snap', '--compression', 'xz', PosixPath('/root/prime'), PosixPath('/root/project')]' returned non-zero exit status 1.
2024-04-17 16:02:38.497 Executing on host: lxc --project snapcraft config device show local:snapcraft-tinmop-on-amd64-for-amd64-391742
2024-04-17 16:02:38.560 Executing on host: lxc --project snapcraft config device remove local:snapcraft-tinmop-on-amd64-for-amd64-391742 disk-/root/project
2024-04-17 16:02:39.118 Executing on host: lxc --project snapcraft stop local:snapcraft-tinmop-on-amd64-for-amd64-391742
2024-04-17 16:02:44.497 Failed to execute pack in instance.
2024-04-17 16:02:44.507 Traceback (most recent call last):
2024-04-17 16:02:44.507   File "/snap/snapcraft/11040/lib/python3.10/site-packages/snapcraft/parts/lifecycle.py", line 482, in _run_in_provider
2024-04-17 16:02:44.507     instance.execute_run(cmd, check=True, cwd=output_dir)
2024-04-17 16:02:44.507   File "/snap/snapcraft/11040/lib/python3.10/site-packages/craft_providers/lxd/lxd_instance.py", line 293, in execute_run
2024-04-17 16:02:44.507     return self.lxc.exec(
2024-04-17 16:02:44.507   File "/snap/snapcraft/11040/lib/python3.10/site-packages/craft_providers/lxd/lxc.py", line 387, in exec
2024-04-17 16:02:44.507     return runner(final_cmd, timeout=timeout, check=check, **kwargs)
2024-04-17 16:02:44.507   File "/snap/snapcraft/11040/usr/lib/python3.10/subprocess.py", line 526, in run
2024-04-17 16:02:44.507     raise CalledProcessError(retcode, process.args,
2024-04-17 16:02:44.507 subprocess.CalledProcessError: Command '['lxc', '--project', 'snapcraft', 'exec', 'local:snapcraft-tinmop-on-amd64-for-amd64-391742', '--cwd', '/root/project', '--', 'env', 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin', 'SNAPCRAFT_MANAGED_MODE=1', 'DEBIAN_FRONTEND=noninteractive', 'DEBCONF_NONINTERACTIVE_SEEN=true', 'DEBIAN_PRIORITY=critical', 'snapcraft', 'pack', '--verbosity=brief', '--build-for', 'amd64']' returned non-zero exit status 1.

stage-packages are included in your snap and are used at runtime of your application when it is installed on the users system …

build-packages are automatically installed in your build environment when actually building the snap …

as such the build-packages list is usually full of -dev package names while the stage-packages list holds the actual binaries and libs used when your app is being executed

the above and following lines show that your install script does not respect the $DESTDIR variable … what your script does there is to actually install stuff into the build environment, not into the snap … make sure all your install -c ... calls properly use the DESTDIR variables to make sure the built artifacts end up in parts/<partname>/install so snapcraft can actually make use of them …

Hi!

stage-packages are included in your snap and are used at runtime of your application when it is installed on the users system …

So i guess i have to add the libraries to stage-packages and the headers to build-packages.

Thanks, i believe that the installing script generated by autotools does respect the DESTDIR variable but when i try to force it using make install destdir=$DESTDIR in the override-build like that:

[...]
override-build: |
      ./configure --prefix=/usr/
      bash quick_quicklisp.sh --do-not-prompt
      make
      make install destdir=$DESTDIR

snap complains that the variable DESTDIR is unbound.

Thanks!
C.

Ah, might be that this is handled only of you do not use an override-build setup.

Try replacing $DESTDIR with $CRAFT_PART_INSTALL, that should be set in any case (and point to the same directory)

Hi!

Ah, might be that this is handled only of you do not use an override-build setup. Try replacing $DESTDIR with $CRAFT_PART_INSTALL, that should be set in any case (and point to the same directory)

It worked like a charm!

And then i learnt about override-pull, so i got rid of override-pull and the package is still built after this modification. There are only two problems left, but this time when the program is running:

  • it is not able to find the shared libraries:
Error opening shared object "libSDL2-2.0.so.0":
  libpulsecommon-15.99.so: cannot open shared object file: No such file or directory.

  • moreover is not able to load a shared library that has been built during the compilation phase:
 Error opening shared object "/root/.cache/common-lisp/sbcl-2.1.11.debian-linux-x64/root/quicklisp/dists/quicklisp/software/osicat-20231021-git/posix/libosicat.so":
  /root/.cache/common-lisp/sbcl-2.1.11.debian-linux-x64/root/quicklisp/dists/quicklisp/software/osicat-20231021-git/posix/libosicat.so: cannot open shared object file: Permission denied.

But, anyway, your help has been precious and allowed me to do a big step towards the goal.

Bye!
C.

See:

Hi!

Thanks to your suggestion i made progress, and i was able to run the program!

Now i have stepped into another problem, when the program run it fails to find system wide configuration file:

$ tinmop
Cannot find "shared.conf" in either "/usr/etc/tinmop/shared.conf" or "/home/cage/snap/tinmop/x1/.config/tinmop/shared.conf"

Is OK if the second path does not exists but the first one is needed as contains default configuration and, if not found, render the software unable to run.

The path “/usr/etc/tinmop/shared.conf” exists under “/snap/tinmop/” i wonder if the problem is in the generated makefile, in fact i set these system wide path when the package is built:


CONF_PATH_FILE       = src/config.lisp

CONF_PATH_FILE_IN    = src/config.lisp.in

[...]

$(CONF_PATH_FILE):  
	grep "^;" $(CONF_PATH_FILE_IN)                          >  $(CONF_PATH_FILE)
	echo -e "(in-package :config)\n"                        >> $(CONF_PATH_FILE);
	echo "(alexandria:define-constant +sys-data-dir+"       >> $(CONF_PATH_FILE);
	echo -e "\"$(pkgdatadir)\" :test #'string=)\n"          >> $(CONF_PATH_FILE);

	echo "(alexandria:define-constant +sys-conf-dir+"       >> $(CONF_PATH_FILE);
	echo -e  "\"$(confdir)\" :test #'string=)\n"            >> $(CONF_PATH_FILE);

	echo "(alexandria:define-constant +catalog-dir+"        >> $(CONF_PATH_FILE);
	echo -e "\""$(localedir)"\" :test #'string=)\n"         >> $(CONF_PATH_FILE);

Seems to me that i have to, someway, prepend $SNAP to $(pkgdatadir), $(confdir) and $(localedir) too, but how?

for reference below is the new snapcraft file:

name: tinmop # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
description: |
  This is my-snap's description. You have a paragraph or two to tell the
  most important story about your snap. Keep it under 100 words though,
  we live in tweetspace and your description wants to look good in the snap
  store.
apps:
  tinmop:
    command: usr/bin/tinmop
    environment:
      LD_LIBRARY_PATH: $LD_LIBRARY_PATH:$SNAP/usr/lib/:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pulseaudio
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
layout:
  /usr/share/tinmop:
    bind: $SNAP/usr/share/tinmop
  /etc/tinmop:
    bind: $SNAP/usr/etc/tinmop
parts:
  tinmop-bin:
    # See 'snapcraft plugins'
    plugin: autotools
    source: "https://codeberg.org/cage/tinmop.git"
    autotools-configure-parameters:
      - --prefix=/usr
    source-type: "git"
    source-branch: "master"
    build-packages:
      - curl
      - file
      - gcc
      - gettext
      - gettext-base
      - git
      - gpg
      - imagemagick
      - libgettextpo-dev
      - libgettextpo0
      - libncurses-dev
      - libsdl2-dev
      - libsqlite3-dev
      - libssl-dev
      - libturbojpeg0-dev
      - man-db
      - openssl
      - sbcl
      - tk
      - unzip
      - xdg-utils
    stage-packages:
      - file
      - imagemagick
      - libncursesw6
      - libsdl2-2.0-0
      - libsqlite3-0
      - libssl3
      - libturbojpeg
      - libgl1
      - man-db
      - openssl
      - pkgconf
      - tk
      - unzip
      - xdg-utils
    override-pull: |
      craftctl default
      ./configure --prefix=/usr/
      bash quick_quicklisp.sh --do-not-prompt

Maybe i have to change the prefix here?

OK, the problem with the configuration file was here:

/etc/tinmop:
    bind: $SNAP/usr/etc/tinmop

instead of:

/usr//etc/tinmop:
    bind: $SNAP/usr/etc/tinmop

Now the executable successfully finds the configuration files!

There is only just another problem likely the last one!

My software uses a bunch of external executable (nano, openssl, tk, man), i have included them into the stage-packages section of the snapcraft file but my software fails to find them; the absolute path for each of them is built when configure script is run and hardcoded in config.lisp, maybe the problem is here?

EDIT

These are the values in config.lisp after: snapcraft prime --shell

(alexandria:define-constant +openssl-bin+     "/root/stage/usr/bin/openssl"           :test #'string=)

(alexandria:define-constant +xdg-open-bin+    "/root/stage/usr/bin/xdg-open"          :test #'string=)

(alexandria:define-constant +unzip-bin+       "/root/stage/usr/bin/unzip"             :test #'string=)

(alexandria:define-constant +man-bin+         "/root/stage/usr/bin/man"               :test #'string=)

(alexandria:define-constant +montage-bin+     "/usr/bin/montage"           :test #'string=)

(alexandria:define-constant +file-bin+        "/root/stage/usr/bin/file"              :test #'string=)

Seems all wrong except, oddly enough, the path for montage, i wonder what is happening. :hushed:

Bye!
C.