Trying to make a snap of FreeBASIC : ld: cannot find -l*

Greetings, I’m new here and I’m trying to build my first snap.
I’m trying to create a snap of the FreeBASIC compiler, and I got as far as getting a ‘hello world’ program to compile with it.
However, when I try to compile anything more complex, the compiler simply can’t see the ‘.a’ libraries it needs.
In a regular installation, the ‘.a’ files are located in /usr/lib/x86_64-linux-gnu/ .
In my snap, they end up in ‘/snap/freebasic/current/usr/lib/x86_64-linux-gnu/’, but when the compiler calls ‘ld’, it just can’t see them.
How do I fix that?
Thanks in advance!

This is what I have so far:

name: freebasic # you probably want to 'snapcraft register <name>'

base: core18

version: '1.07.1' # just for humans, typically '1.2+git' or '1.3.2'

summary: Free/open source (GPL), BASIC compiler.  # 79 char long summary

description: |
  FreeBASIC is a self-hosting compiler which makes use of the GNU binutils
  programming tools as backends and can produce console, graphical/GUI executables,
  dynamic and static libraries. FreeBASIC fully supports the use of C libraries and
  has partial C++ library support. This lets programmers use and create libraries
  for C and many other languages. It supports a C style preprocessor, capable of
  multiline macros, conditional compiling and file inclusion.

grade: devel # must be 'stable' to release into candidate/stable channels  #devel

confinement: devmode # use 'strict' once you have the right plugs and slots  #devmode


architectures:
  - build-on: [amd64, i386]
    run-on: [amd64, i386]


parts:
  
  fbc:
    
    plugin: dump

    source: ../usr/local/bin

    organize:
      fbc: usr/local/bin/fbc
      fbc64: usr/local/bin/fbc64
      ar: usr/bin/ar
      as: usr/bin/as
      gcc: usr/bin/gcc
      gdb: usr/bin/gdb
      ld: usr/bin/ld
    
    build-attributes: [keep-execstack]

    stage-packages: [gcc-multilib, build-essential, libc6-dev, libstdc++6, libtinfo5, libncurses-dev, libx11-dev, libxext-dev, libxpm-dev, libxrandr-dev, libxrender-dev, zlib1g, libzip-dev, libgl-dev] 



  local:
    
    plugin: dump

    source: ../usr

    organize:
      local: usr/local


apps:

  fbc:

    command: usr/local/bin/fbc

    plugs: [home]

Hi,

Let’s start with two main issues, see below. Then one could wonder why you’re packaging pre-compiled FreeBASIC programs instead of building FreeBASIC from sources, but let’s leave that for later.

Embark dependencies the proper way: stage-packages

Programs ar, as and ld are part of binutils and might require additional files to work properly. The same goes for gcc (part of gcc) and gdb (part of gdb). In order to embark all required depdencies I suggest you replace:

organize:
      ar: usr/bin/ar
      as: usr/bin/as
      gcc: usr/bin/gcc
      gdb: usr/bin/gdb
      ld: usr/bin/ld

with:

        stage-packages: [binutils, gcc, gdb]

Actually most of these packages (including gcc) are part of the build-essential list of individual packages. Therefore I suggest you try to reduce your stage-packages list to something minimal and start from there:

    stage-packages: [build-essential, gdb] 

Access gcc, ld from FreeBASIC

Then fbc/fbc64 need to run gcc and ld if I correctly understand how FreeBASIC works. However fbc/fbc64 expect gcc and ld to be available as /usr/bin/gcc and /usr/bin/ld but these are actually embarked as $SNAP/usr/bin/gcc and $SNAP/usr/bin/ld. Add a layout to your snpacraft.yaml file:

layout:
    /usr/bin/gcc:
        bind-file: $SNAP/usr/bin/gcc
    /usr/bin/ld:
        bind-file: $SNAP/usr/bin/ld
    /usr/bin/gdb:
        bind-file: $SNAP/usr/bin/gdb

Also add other programs that are required by FreeBasic. I suspect as and ar are not explicitly needed by FreeBasic - but if they are directly needed just add them to the layout.

Just read in the FreeBASIC README file:

      To compile FB programs, please install the following packages (names may
      vary depending on your Linux distribution):
        Debian/Ubuntu:
          gcc libncurses5-dev libffi-dev libgl1-mesa-dev
          libx11-dev libxext-dev libxrender-dev libxrandr-dev libxpm-dev

So you might indeed need to embark additional packages that are not part of core18:

    stage-packages: [build-essential, gdb, libncurses5-dev, libffi-dev, libgl1-mesa-dev, libx11-dev, libxext-dev, libxrender-dev, libxrandr-dev, libxpm-dev] 

Finally do you really need this?

    build-attributes: [keep-execstack]

You’re not building FreeBASIC from sources, just copying final programs with the dumpplugin. Therefore this shouldn’t be needed.

Hello Dimitri!

Thank you for putting me in the right path!

The reason I’m doing this is because executables compiled with FreeBASIC in 20.04 beta are not compatible with 18.04 because of the GLIBC version.

I want to use FreeBASIC on 20.04 and still be able to create executables that are compatible with the older distros.

FreeBASIC does need ‘as’ and ‘ar’, so I’m adding them.

Now I’m having this problem adding the layout:

Failed to load plugin: properties failed to load for fbc: Additional properties are not allowed (‘layout’ was unexpected)

Another thing, the ‘fbc’ command ends up as ‘freebasic.fbc’, and I couldn’t understand why.

This is what I have so far:

name: freebasic # you probably want to 'snapcraft register <name>'

base: core18

version: '1.07.1' # just for humans, typically '1.2+git' or '1.3.2'

summary: Free/open source (GPL), BASIC compiler.  # 79 char long summary

description: |
  FreeBASIC is a self-hosting compiler which makes use of the GNU binutils
  programming tools as backends and can produce console, graphical/GUI executables,
  dynamic and static libraries. FreeBASIC fully supports the use of C libraries and
  has partial C++ library support. This lets programmers use and create libraries
  for C and many other languages. It supports a C style preprocessor, capable of
  multiline macros, conditional compiling and file inclusion.

grade: devel # must be 'stable' to release into candidate/stable channels  #devel

confinement: devmode # use 'strict' once you have the right plugs and slots  #devmode


architectures:
  - build-on: [amd64, i386]
    run-on: [amd64, i386]


parts:
  
  fbc:
    
    plugin: dump

    source: ../usr/local/bin
        

    stage-packages: [gcc-multilib, binutils, gcc, gdb, build-essential, libffi-dev, libgl1-mesa-dev, libc6-dev, libstdc++6, libtinfo5, libncurses-dev, libx11-dev, libxext-dev, libxpm-dev, libxrandr-dev, libxrender-dev, zlib1g, libzip-dev, libgl-dev]
    

    layout:
      /usr/bin/ar:
        bind-file: $SNAP/usr/bin/ar
      /usr/bin/as:
        bind-file: $SNAP/usr/bin/as
      /usr/bin/gcc:
        bind-file: $SNAP/usr/bin/gcc
      /usr/bin/gdb:
        bind-file: $SNAP/usr/bin/gdb
      /usr/bin/ld:
        bind-file: $SNAP/usr/bin/ld


  local:
    
    plugin: dump

    source: ../usr

    organize:
      local: usr/local



apps:

  fbc:

    command: usr/local/bin/fbc
    
    plugs: [home]

your layout: block is in the wrong place. It should be top-level (no indentation) and not part of the parts: block.

Thank you Daniel.
I tried that, but now I get:

Issues while validating snapcraft.yaml: Additional properties are not allowed (‘layout’ was unexpected)

Here’s my WIP:

name: freebasic # you probably want to 'snapcraft register <name>'

base: core18

version: '1.07.1' # just for humans, typically '1.2+git' or '1.3.2'

summary: Free/open source (GPL), BASIC compiler.  # 79 char long summary

description: |
  FreeBASIC is a self-hosting compiler which makes use of the GNU binutils
  programming tools as backends and can produce console, graphical/GUI executables,
  dynamic and static libraries. FreeBASIC fully supports the use of C libraries and
  has partial C++ library support. This lets programmers use and create libraries
  for C and many other languages. It supports a C style preprocessor, capable of
  multiline macros, conditional compiling and file inclusion.

grade: devel # must be 'stable' to release into candidate/stable channels  #devel

confinement: devmode # use 'strict' once you have the right plugs and slots  #devmode


architectures:
  - build-on: [amd64, i386]
    run-on: [amd64, i386]




parts:
  
  fbc:
    
    plugin: dump

    source: ../usr/local/bin

        
    stage-packages: [gcc-multilib, binutils, gcc, gdb, build-essential, libffi-dev, libgl1-mesa-dev, libc6-dev, libstdc++6, libtinfo5, libncurses-dev, libx11-dev, libxext-dev, libxpm-dev, libxrandr-dev, libxrender-dev, zlib1g, libzip-dev, libgl-dev]
    


  local:
    
    plugin: dump

    source: ../usr

    organize:
      local: usr/local



apps:

  fbc:

    command: usr/local/bin/fbc
    
    plugs: [home]

    
layout:

  /usr/bin/ar:
    bind-file: $SNAP/usr/bin/ar
        
  /usr/bin/as:
    bind-file: $SNAP/usr/bin/as
  
  /usr/bin/gcc:
    bind-file: $SNAP/usr/bin/gcc
  
  /usr/bin/gdb:
    bind-file: $SNAP/usr/bin/gdb
  /usr/bin/ld:
    bind-file: $SNAP/usr/bin/ld

Hm, I think it’s the snapcraft version. It fails on 18.04 but runs on 20.04.

EDIT:

Now I’m getting:

Failed to pull source: unable to determine source type of '../usr'.
Check that the URL is correct or consider specifying `source-type` for this part. See `snapcraft help sources` for more information. 

The files are right there. :sob:

Using source-type: local didn’t work either.

'/root/usr' is not a directory

You should have the same version of snapcraft on Ubuntu 18.04 and 20.04. Please install snapcraft as a recent snap. On my own machine:

$ which snapcraft 
/snap/bin/snapcraft
$ 
$ snapcraft --version
snapcraft, version 3.11
$ 

Put layout before parts. That’s probably not required but all examples are built like that, try to mimic examples for now.

Concerning architectures, keep either amd64 or i386 depending on the platform you have built fbc/fbc64 on. For example:

architectures:
    - build-on: amd64

What is the output of this command?

file /usr/local/bin/fcb*

Then why does snapcraft.yaml contain two parts? As far as I can there only one “part” or target: fbc. The rest are dependencies. Also I udnesrtand the organize part used to work. If so why have you changed it?

Try something like this:

parts:
  fbc:
    source: /path/to/files
    plugin: dump
    stage-packages: [build-essential, gcc-multilib, gdb, libffi-dev, libgl1-mesa-dev, libc6-dev, libstdc++6, libtinfo5, libncurses-dev, libx11-dev, libxext-dev, libxpm-dev, libxrandr-dev, libxrender-dev, zlib1g, libzip-dev, libgl-dev]
    organize:
      bin/fbc: fbc
      bin/fbc64: fbc64

In my system I have renamed fbc and made a link so I can have both 32-bit and 64-bit installed at the same time:

file /usr/local/bin/fbc*
/usr/local/bin/fbc:   symbolic link to fbc64
/usr/local/bin/fbc32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, not stripped
/usr/local/bin/fbc64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped

Do I need to ‘dump’ files from my system?
Because I was trying to get the files from a folder in the user directory.

Why would you need both 32-bit and 64-bit? The 64-bit program won’t run on i386 architectures. The 32-bit program is possibly useless on amd64 architectures. Whatever, that’s shouldn’t be a problem for creating the snap.

I don’t know about the location of the “source” files fcb, fcb32 and fcb64, I’ve only experimented creating snaps from sources and in my case the source is . or https://github.com/org/app.git.

Does it work for you or not?

Hey! Sorry about the delay, I was offline.

The reason I wanted both 32 and 64-bit…

I create games, and usually zip a package containing binaries for 32-bit Linux, 64-bit Linux and win32.

I can usually cross-compile. The win32 version won’t be a problem for me on 20.04, because it has nothing to do with the GLIBC version.

Well, maybe it’s time to drop the 32-bit Linux builds, who still uses it anyway?

Here’s what I have so far:

name: freebasic # you probably want to 'snapcraft register ’

base: core18

version: ‘1.07.1’ # just for humans, typically ‘1.2+git’ or ‘1.3.2’

summary: Free/open source (GPL), BASIC compiler. # 79 char long summary

description: |
FreeBASIC is a self-hosting compiler which makes use of the GNU binutils
programming tools as backends and can produce console, graphical/GUI executables,
dynamic and static libraries. FreeBASIC fully supports the use of C libraries and
has partial C++ library support. This lets programmers use and create libraries
for C and many other languages. It supports a C style preprocessor, capable of
multiline macros, conditional compiling and file inclusion.

grade: devel # must be ‘stable’ to release into candidate/stable channels #devel

confinement: devmode # use ‘strict’ once you have the right plugs and slots #devmode

architectures:

  • build-on: [amd64]
    run-on: [amd64]

parts:
fbc:
source: ./myroot
source-type: local
plugin: dump
stage-packages: [build-essential, gcc-multilib, gdb, libffi-dev, libgl1-mesa-dev, libc6-dev, libstdc++6, libtinfo5, libncurses-dev, libx11-dev, libxext-dev, libxpm-dev, libxrandr-dev, libxrender-dev, zlib1g, libzip-dev, libgl-dev]

apps:

fbc:

command: usr/local/bin/fbc

plugs: [home]

I have put everything I need in the right place, inside the “myroot” folder, so I don’t need to organize. Way easier.

I got it to snap again, I can install it and use it to compile a “hello world” program.

But I still have that problem with ld not finding the files.

The layout thing didn’t not work, because as, ar, gcc, gdb and ld are not files but links.

Trying to bind the target files instead of the links didn’t solve it either.

Almost there, I think.

I finally got it working.

name: freebasic # you probably want to 'snapcraft register ’

base: core18

version: ‘1.07.1’ # just for humans, typically ‘1.2+git’ or ‘1.3.2’

summary: Free/open source (GPL), BASIC compiler. # 79 char long summary

description: | FreeBASIC is a self-hosting compiler which makes use of the GNU binutils programming tools as backends and can produce console, graphical/GUI executables, dynamic and static libraries. FreeBASIC fully supports the use of C libraries and has partial C++ library support. This lets programmers use and create libraries for C and many other languages. It supports a C style preprocessor, capable of multiline macros, conditional compiling and file inclusion.

grade: devel # must be ‘stable’ to release into candidate/stable channels #devel

confinement: devmode # use ‘strict’ once you have the right plugs and slots #devmode

architectures:

  • build-on: [amd64] run-on: [amd64]

layout:

/usr/X11R6/lib: symlink: $SNAP/usr/lib/x86_64-linux-gnu

/usr/lib/x86_64-linux-gnu/libm-2.27.a: symlink: $SNAP/usr/lib/x86_64-linux-gnu/libm-2.27.a

/usr/lib/x86_64-linux-gnu/libmvec_nonshared.a: symlink: $SNAP/usr/lib/x86_64-linux-gnu/libmvec_nonshared.a

/usr/lib/x86_64-linux-gnu/libpthread_nonshared.a: symlink: $SNAP/usr/lib/x86_64-linux-gnu/libpthread_nonshared.a

/usr/lib/x86_64-linux-gnu/libc_nonshared.a: symlink: $SNAP/usr/lib/x86_64-linux-gnu/libc_nonshared.a

parts: fbc: source: ./myroot source-type: local plugin: dump stage-packages: [build-essential, gdb, libffi-dev, libgl1-mesa-dev, libc6-dev, libstdc++6, libtinfo5, libncurses-dev, libx11-dev, libxext-dev, libxpm-dev, libxrandr-dev, libxrender-dev, zlib1g, libzip-dev, libgl-dev]

apps:

fbc:

command: usr/bin/fbc

plugs: [home]

Not the most elegant solutions, but it works for my usecase.

There’s something weird about ld. Sometimes it can’t find the libraries, even if they are there.

A verbose output helped me figure out where it was looking.

attempt to open /snap/freebasic/x1/usr/local/bin/…/lib/freebasic/linux-x86_64/libX11.so failed attempt to open /snap/freebasic/x1/usr/local/bin/…/lib/freebasic/linux-x86_64/libX11.a failed attempt to open ./libX11.so failed attempt to open ./libX11.a failed attempt to open /snap/freebasic/x1/usr/bin/…/lib/gcc/x86_64-linux-gnu/7/libX11.so failed attempt to open /snap/freebasic/x1/usr/bin/…/lib/gcc/x86_64-linux-gnu/7/libX11.a failed attempt to open /usr/X11R6/lib/libX11.so failed attempt to open /usr/X11R6/lib/libX11.a failed attempt to open //usr/local/lib/x86_64-linux-gnu/libX11.so failed attempt to open //usr/local/lib/x86_64-linux-gnu/libX11.a failed attempt to open //lib/x86_64-linux-gnu/libX11.so failed attempt to open //lib/x86_64-linux-gnu/libX11.a failed attempt to open //usr/lib/x86_64-linux-gnu/libX11.so failed attempt to open //usr/lib/x86_64-linux-gnu/libX11.a failed attempt to open //usr/lib/x86_64-linux-gnu64/libX11.so failed attempt to open //usr/lib/x86_64-linux-gnu64/libX11.a failed attempt to open //usr/local/lib64/libX11.so failed attempt to open //usr/local/lib64/libX11.a failed attempt to open //lib64/libX11.so failed attempt to open //lib64/libX11.a failed attempt to open //usr/lib64/libX11.so failed attempt to open //usr/lib64/libX11.a failed attempt to open //usr/local/lib/libX11.so failed attempt to open //usr/local/lib/libX11.a failed attempt to open //lib/libX11.so failed attempt to open //lib/libX11.a failed attempt to open //usr/lib/libX11.so failed attempt to open //usr/lib/libX11.a failed attempt to open //usr/x86_64-linux-gnu/lib64/libX11.so failed attempt to open //usr/x86_64-linux-gnu/lib64/libX11.a failed attempt to open //usr/x86_64-linux-gnu/lib/libX11.so failed attempt to open //usr/x86_64-linux-gnu/lib/libX11.a failed ld: cannot find -lX11

It can find the files when I put the link at the X11R6 directory. It doesn’t have the double dash (//) at the beginning, so maybe that’s what’s messing it up.

I could install the snap and compile my most complex projects on it.

The resulting binaries ran both on 18.04 and 20.04. :slight_smile:

Thank you for your help!

My WIP is here: https://sourceforge.net/projects/freebasic-snap/