New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function to bundle libstdc++ and decide at runtime if it's needed #185

Closed
wants to merge 2 commits into
base: master
from

Conversation

Projects
None yet
3 participants
@darealshinji
Contributor

darealshinji commented Feb 15, 2017

Should close #173.

Make sure to add these scripts to one of your repositories and adjust the download URLs in get_gcclibs().

If you want to run a test, you can modify i.e. the wxHexEditor recipe and run the AppImage with the environment variable DEBUG=1:

--- a/recipes/wxhexeditor/Recipe
+++ b/recipes/wxhexeditor/Recipe
@@ -3,7 +3,8 @@ mkdir -p $APP/$APP.AppDir/usr/bin
 
 cd $APP/
 
-wget -q https://github.com/probonopd/AppImages/raw/master/functions.sh -O ./functions.sh
+#wget -q https://github.com/probonopd/AppImages/raw/master/functions.sh -O ./functions.sh
+cp $HOME/Downloads/AppImages/functions.sh .
 . ./functions.sh
 
 wget -c "http://downloads.sourceforge.net/project/wxhexeditor/wxHexEditor/v0.23%20Beta/wxHexEditor-v0.23-Linux_x86_64.tar.bz2"
@@ -40,6 +41,8 @@ echo $VERSION
 XAPP=wxHexEditor
 get_desktopintegration $XAPP.desktop
 
+get_gcclibs
+
 cd .. # Go out of AppDir
 
 generate_appimage
@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Feb 15, 2017

Member

Thanks @darealshinji

Make sure to add these scripts to one of your repositories and adjust the download URLs in get_gcclibs().

Had a quick glance at these, would you mind to quickly explain what these do and why they are needed?

Member

probonopd commented Feb 15, 2017

Thanks @darealshinji

Make sure to add these scripts to one of your repositories and adjust the download URLs in get_gcclibs().

Had a quick glance at these, would you mind to quickly explain what these do and why they are needed?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Feb 15, 2017

Contributor

build.sh is the script used to build libgcc, libstdc++, readelf and the test binary, all the stuff which is used by the wrapper script.
run.sh is the wrapper script which is placed into ./usr/bin.

Contributor

darealshinji commented Feb 15, 2017

build.sh is the script used to build libgcc, libstdc++, readelf and the test binary, all the stuff which is used by the wrapper script.
run.sh is the wrapper script which is placed into ./usr/bin.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Feb 16, 2017

Member

Do we really need to compile these ourselves? Or could we fetch the same binaries, e.g., from debian oldstable?

Member

probonopd commented Feb 16, 2017

Do we really need to compile these ourselves? Or could we fetch the same binaries, e.g., from debian oldstable?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Feb 16, 2017

Contributor

libgcc and libstdc++ need to be from GCC 5 or GCC6 to support C++14, but they need to be build on an old distro to be compatible with older glibc versions. But I could try to build them for Ubuntu 12.04 from a PPA.

The readelf binary from Debian wheezy's binutils package depends only on libz and libc and seems to work for me.

The test binary can be compiled with a simple one-liner: echo "int main(){return 0;}" | cc -Os -s -o testrt -xc - -Wl,--no-as-needed -lgcc_s -lstdc++

Contributor

darealshinji commented Feb 16, 2017

libgcc and libstdc++ need to be from GCC 5 or GCC6 to support C++14, but they need to be build on an old distro to be compatible with older glibc versions. But I could try to build them for Ubuntu 12.04 from a PPA.

The readelf binary from Debian wheezy's binutils package depends only on libz and libc and seems to work for me.

The test binary can be compiled with a simple one-liner: echo "int main(){return 0;}" | cc -Os -s -o testrt -xc - -Wl,--no-as-needed -lgcc_s -lstdc++

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Feb 16, 2017

Member

Can you imagine any solution that might achieve the same goal without having to compile anything? I am a bit hesitant to add this, because so far generating an AppImage does not need a compiler (once you have a precompiled appimagetool)...

Member

probonopd commented Feb 16, 2017

Can you imagine any solution that might achieve the same goal without having to compile anything? I am a bit hesitant to add this, because so far generating an AppImage does not need a compiler (once you have a precompiled appimagetool)...

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Feb 16, 2017

Contributor

The end user doesn't need to compile anything. But to ensure backwards compatibility libgcc and libstdc++ from recent gcc versions (currently 6.3) are required to be build on an older distro such as Ubuntu 12.04 or Debian Wheezy.

For example: I built Aegisub on Ubuntu 12.04. This requires C++11, which the compilers on 12.04 don't support. So I built gcc6 from source and compiled Aegisub and its dependencies. Minimum glibc version required is now 2.14. But it needs glibcxx 3.4.21, Ubuntu 12.04 provides only 3.4.16. Ubuntu 16.04 has glibcxx 3.4.21, but that library needs glibc 2.18, so it can't be used on Ubuntu 12.04.

Maybe the builds from here could be used. The readelf binary could be fetched from any older system I guess, though building it from elftoolchain sources would mean there's no copyleft.

edit:

wget -c https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+files/libgcc1_6.2.0-3ubuntu11~12.04_i386.deb
wget -c https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+files/libgcc1_6.2.0-3ubuntu11~12.04_amd64.deb
wget -c https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+files/libstdc++6_6.2.0-3ubuntu11~12.04_amd64.deb
wget -c https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+files/libstdc++6_6.2.0-3ubuntu11~12.04_i386.deb
#wget -c http://security.debian.org/debian-security/pool/updates/main/b/binutils/binutils_2.22-8+deb7u3_amd64.deb
#wget -c http://security.debian.org/debian-security/pool/updates/main/b/binutils/binutils_2.22-8+deb7u3_i386.deb
wget -c https://launchpad.net/~djcj/+archive/ubuntu/tools/+files/elftoolchain_0.7.1-0ppa1~precise3_amd64.deb
wget -c https://launchpad.net/~djcj/+archive/ubuntu/tools/+files/elftoolchain_0.7.1-0ppa1~precise3_i386.deb

for a in amd64 i386 ; do
  for f in *_${a}.deb ; do
    ar p $f data.tar.gz | tar xz
  done
  mkdir $a
  cp ./usr/lib/elftoolchain/readelf ./lib/*/libgcc_s.so.1 ./usr/lib/*/libstdc++.so.6 $a
  rm -rf usr lib
done

echo "int main(){return 0;}" | cc -m64 -Os -s -o amd64/testrt -xc - -Wl,--no-as-needed -lgcc_s -lstdc++
echo "int main(){return 0;}" | cc -m32 -Os -s -o i386/testrt -xc - -Wl,--no-as-needed -lgcc_s -lstdc++
Contributor

darealshinji commented Feb 16, 2017

The end user doesn't need to compile anything. But to ensure backwards compatibility libgcc and libstdc++ from recent gcc versions (currently 6.3) are required to be build on an older distro such as Ubuntu 12.04 or Debian Wheezy.

For example: I built Aegisub on Ubuntu 12.04. This requires C++11, which the compilers on 12.04 don't support. So I built gcc6 from source and compiled Aegisub and its dependencies. Minimum glibc version required is now 2.14. But it needs glibcxx 3.4.21, Ubuntu 12.04 provides only 3.4.16. Ubuntu 16.04 has glibcxx 3.4.21, but that library needs glibc 2.18, so it can't be used on Ubuntu 12.04.

Maybe the builds from here could be used. The readelf binary could be fetched from any older system I guess, though building it from elftoolchain sources would mean there's no copyleft.

edit:

wget -c https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+files/libgcc1_6.2.0-3ubuntu11~12.04_i386.deb
wget -c https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+files/libgcc1_6.2.0-3ubuntu11~12.04_amd64.deb
wget -c https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+files/libstdc++6_6.2.0-3ubuntu11~12.04_amd64.deb
wget -c https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+files/libstdc++6_6.2.0-3ubuntu11~12.04_i386.deb
#wget -c http://security.debian.org/debian-security/pool/updates/main/b/binutils/binutils_2.22-8+deb7u3_amd64.deb
#wget -c http://security.debian.org/debian-security/pool/updates/main/b/binutils/binutils_2.22-8+deb7u3_i386.deb
wget -c https://launchpad.net/~djcj/+archive/ubuntu/tools/+files/elftoolchain_0.7.1-0ppa1~precise3_amd64.deb
wget -c https://launchpad.net/~djcj/+archive/ubuntu/tools/+files/elftoolchain_0.7.1-0ppa1~precise3_i386.deb

for a in amd64 i386 ; do
  for f in *_${a}.deb ; do
    ar p $f data.tar.gz | tar xz
  done
  mkdir $a
  cp ./usr/lib/elftoolchain/readelf ./lib/*/libgcc_s.so.1 ./usr/lib/*/libstdc++.so.6 $a
  rm -rf usr lib
done

echo "int main(){return 0;}" | cc -m64 -Os -s -o amd64/testrt -xc - -Wl,--no-as-needed -lgcc_s -lstdc++
echo "int main(){return 0;}" | cc -m32 -Os -s -o i386/testrt -xc - -Wl,--no-as-needed -lgcc_s -lstdc++
@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Feb 17, 2017

Contributor

All required binaries are now build on CentOS Docker image and uploaded to the release section of my fork. The script will fetch them from there.

Contributor

darealshinji commented Feb 17, 2017

All required binaries are now build on CentOS Docker image and uploaded to the release section of my fork. The script will fetch them from there.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Feb 17, 2017

Member

Well, if I am supposed to pull this then it should be self-standing, i.e., everything should be built and uploaded within the probonopd/AppImages repository.

Member

probonopd commented Feb 17, 2017

Well, if I am supposed to pull this then it should be self-standing, i.e., everything should be built and uploaded within the probonopd/AppImages repository.

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Feb 18, 2017

Contributor

Sure. You should put build.sh and run.sh (from here) on a separate branch then, to avoid unneeded rebuilds (I don't think I can make a PR for that?).

Contributor

darealshinji commented Feb 18, 2017

Sure. You should put build.sh and run.sh (from here) on a separate branch then, to avoid unneeded rebuilds (I don't think I can make a PR for that?).

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Mar 20, 2017

Contributor

Anything new on this?

If you want AppImages to test (both are still using GNU's readelf though):

Contributor

darealshinji commented Mar 20, 2017

Anything new on this?

If you want AppImages to test (both are still using GNU's readelf though):

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Mar 20, 2017

Member

Thanks @darealshinji, I am not against this, just haven't seen the need for this in real life so far. And am hesitant to add anything that increases code complexity as long as we can get away without it.

Do others have an opinion on or use case for this?

Member

probonopd commented Mar 20, 2017

Thanks @darealshinji, I am not against this, just haven't seen the need for this in real life so far. And am hesitant to add anything that increases code complexity as long as we can get away without it.

Do others have an opinion on or use case for this?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 3, 2017

Contributor

I moved the stuff to a separate repository: https://github.com/darealshinji/AppImage-gcc-runtime

I still need to add a real description and some information and examples on how to use it.

Contributor

darealshinji commented Apr 3, 2017

I moved the stuff to a separate repository: https://github.com/darealshinji/AppImage-gcc-runtime

I still need to add a real description and some information and examples on how to use it.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 4, 2017

Member

Thanks @darealshinji. Depending on people's need for this we can still consider to merge it in the future.

Member

probonopd commented Apr 4, 2017

Thanks @darealshinji. Depending on people's need for this we can still consider to merge it in the future.

@probonopd probonopd closed this Apr 4, 2017

@darealshinji darealshinji deleted the darealshinji:gcc_libs branch Apr 4, 2017

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 6, 2017

Member

Please see whether this can fix http://discourse.appimage.org/t/im-a-big-fan-of-this-but-graphics-driver-libstdc-conflict/171 - would be a real-life application of this.

Member

probonopd commented Apr 6, 2017

Please see whether this can fix http://discourse.appimage.org/t/im-a-big-fan-of-this-but-graphics-driver-libstdc-conflict/171 - would be a real-life application of this.

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 7, 2017

Contributor

Do you have a download link of emu-player-64-1.0.5.appimage so I can investigate it?

Contributor

darealshinji commented Apr 7, 2017

Do you have a download link of emu-player-64-1.0.5.appimage so I can investigate it?

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd
Member

probonopd commented Apr 7, 2017

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 8, 2017

Contributor

The emu-player needs GLIBCXX 3.4.21 aka libstdc++.so.6.0.21, which is quite new, so for downwards compatibility it needs to be bundled. This looks indeed like a real-life case for using my little mechanism.

Here's the fixed AppDir (I leave bundling and signing to upstream): https://www.dropbox.com/s/otiezrk4kp1n1gz/emu-player-64-1.0.5-fix.AppDir.tar.xz?dl=0

Right now only 64 bit libraries are build on Travis. I didn't bother to check how to build and properly upload for both architectures yet. This is my current .travis.yml:

language: c
compiler: gcc

services:
  - docker

env:
  - DOCKER_IMAGE=library/centos:6.8

script:
  - mkdir -p ./out/
  - docker run -i -v ${PWD}/out:/out -v "${PWD}:/AppImage-gcc-runtime" "$DOCKER_IMAGE" /bin/bash -c "cd /AppImage-gcc-runtime ; yum -y install sudo ; sudo ./build.sh"
  - ls -lh out/*
  - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
  - bash ./upload.sh out/*

branches:
  only:
    - master
Contributor

darealshinji commented Apr 8, 2017

The emu-player needs GLIBCXX 3.4.21 aka libstdc++.so.6.0.21, which is quite new, so for downwards compatibility it needs to be bundled. This looks indeed like a real-life case for using my little mechanism.

Here's the fixed AppDir (I leave bundling and signing to upstream): https://www.dropbox.com/s/otiezrk4kp1n1gz/emu-player-64-1.0.5-fix.AppDir.tar.xz?dl=0

Right now only 64 bit libraries are build on Travis. I didn't bother to check how to build and properly upload for both architectures yet. This is my current .travis.yml:

language: c
compiler: gcc

services:
  - docker

env:
  - DOCKER_IMAGE=library/centos:6.8

script:
  - mkdir -p ./out/
  - docker run -i -v ${PWD}/out:/out -v "${PWD}:/AppImage-gcc-runtime" "$DOCKER_IMAGE" /bin/bash -c "cd /AppImage-gcc-runtime ; yum -y install sudo ; sudo ./build.sh"
  - ls -lh out/*
  - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
  - bash ./upload.sh out/*

branches:
  only:
    - master
@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 8, 2017

Member

The emu-player needs GLIBCXX 3.4.21 aka libstdc++.so.6.0.21, which is quite new, so for downwards compatibility it needs to be bundled.

Which makes me wonder why this is in the first place, couldn't it be compiled with an older version of it? Why don't developers develop against the oldest still-supported LTS, that would save so much trouble. In my experience, trying to bundle a newer libstdc++ is always tricky.

Member

probonopd commented Apr 8, 2017

The emu-player needs GLIBCXX 3.4.21 aka libstdc++.so.6.0.21, which is quite new, so for downwards compatibility it needs to be bundled.

Which makes me wonder why this is in the first place, couldn't it be compiled with an older version of it? Why don't developers develop against the oldest still-supported LTS, that would save so much trouble. In my experience, trying to bundle a newer libstdc++ is always tricky.

@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 8, 2017

Thanks for looking at this for me.

In answer to your question re the requirement of libstdc++.so.6.0.21....well, first of all I attempted to build my project on a clean Ubuntu 12.04 install as this seemed like a reasonable base to start from.

However, due to the use of some C++11 code, the bundled gcc (4.6) was no good. I then looked around for a version of gcc that was later and the only packaged one I could find was 5.4.1. So I installed that, which requires libstdc++.so.6.0.22. I then discovered that this conflicted with the graphics driver on Linux Mint 18 (uses libcstd++so.6.0.21 but wouldn't work with 6.0.22 for some reason I don't understand).

So I then rebuilt my project with 5.4.0, which requires 6.0.21.

It's possible that I can use an earlier gcc - 4.9 perhaps - which would still give me the C++11 features I need, and maybe can use an earlier libcstdc++.

"Why don't developers develop against the oldest still-supported LTS, that would save so much trouble"

Essentially you are asking for developers not to use C++11.....now that might be something I could work around with my own code, but isn't always going to be possible when including third party libraries built from source....

oviano commented Apr 8, 2017

Thanks for looking at this for me.

In answer to your question re the requirement of libstdc++.so.6.0.21....well, first of all I attempted to build my project on a clean Ubuntu 12.04 install as this seemed like a reasonable base to start from.

However, due to the use of some C++11 code, the bundled gcc (4.6) was no good. I then looked around for a version of gcc that was later and the only packaged one I could find was 5.4.1. So I installed that, which requires libstdc++.so.6.0.22. I then discovered that this conflicted with the graphics driver on Linux Mint 18 (uses libcstd++so.6.0.21 but wouldn't work with 6.0.22 for some reason I don't understand).

So I then rebuilt my project with 5.4.0, which requires 6.0.21.

It's possible that I can use an earlier gcc - 4.9 perhaps - which would still give me the C++11 features I need, and maybe can use an earlier libcstdc++.

"Why don't developers develop against the oldest still-supported LTS, that would save so much trouble"

Essentially you are asking for developers not to use C++11.....now that might be something I could work around with my own code, but isn't always going to be possible when including third party libraries built from source....

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 8, 2017

Member

Maybe something along the lines of

sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-4.8 g++-4.8

could do @oviano?

Member

probonopd commented Apr 8, 2017

Maybe something along the lines of

sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-4.8 g++-4.8

could do @oviano?

@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 8, 2017

Thanks probonopd; it might work, but I do like the solution put forward by darealshinji as it does seem to allow the use of a more recent compiler version and seems the best of both Worlds?

Even if gcc 4.8 turned out to work for my project (which I'm not sure about because I know for a start that libVLC, which my application is partially built upon, recommends the use of 4.9) it's still going to need libstdc++.so.6.0.18 (source https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) so I'd still need to bundle libstdc++ anyway for it work on a fresh Ubuntu 12.04 install so it doesn't really save me anything...and in fact means I'd have to re-do a whole load of testing of my application having rebuilt it using an older version of the compiler...

oviano commented Apr 8, 2017

Thanks probonopd; it might work, but I do like the solution put forward by darealshinji as it does seem to allow the use of a more recent compiler version and seems the best of both Worlds?

Even if gcc 4.8 turned out to work for my project (which I'm not sure about because I know for a start that libVLC, which my application is partially built upon, recommends the use of 4.9) it's still going to need libstdc++.so.6.0.18 (source https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) so I'd still need to bundle libstdc++ anyway for it work on a fresh Ubuntu 12.04 install so it doesn't really save me anything...and in fact means I'd have to re-do a whole load of testing of my application having rebuilt it using an older version of the compiler...

@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 8, 2017

@darealshinji - I think you need to append "$@" to the final line of your run.sh script so that command line arguments get passed through?

oviano commented Apr 8, 2017

@darealshinji - I think you need to append "$@" to the final line of your run.sh script so that command line arguments get passed through?

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 8, 2017

Member

If you want it to work on Ubuntu 12.04 then you need to build it on Ubuntu 12.04 or earlier @oviano or you may run into incompatible library issues. The only (bloated; sloppy) workaround would be to bundle everything, including ld-loader and glibc.

This has nothing to do with AppImage specifically, it is just how downward binary compatibility works. Always compile on a system no newer than your oldest system you are targeting.

Member

probonopd commented Apr 8, 2017

If you want it to work on Ubuntu 12.04 then you need to build it on Ubuntu 12.04 or earlier @oviano or you may run into incompatible library issues. The only (bloated; sloppy) workaround would be to bundle everything, including ld-loader and glibc.

This has nothing to do with AppImage specifically, it is just how downward binary compatibility works. Always compile on a system no newer than your oldest system you are targeting.

@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 8, 2017

I am building it on Ubuntu 12.04, but with an updated compiler (5.4.0 instead of 4.6).

Everything is now working fine with @darealshinji modifications.

oviano commented Apr 8, 2017

I am building it on Ubuntu 12.04, but with an updated compiler (5.4.0 instead of 4.6).

Everything is now working fine with @darealshinji modifications.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 8, 2017

Member

Cool, glad to hear that @oviano @darealshinji - so let's think about how to best incorporate this PR.

Member

probonopd commented Apr 8, 2017

Cool, glad to hear that @oviano @darealshinji - so let's think about how to best incorporate this PR.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 8, 2017

Member

@darealshinji can you send a PR that incorporates this in a way it builds everyhting inside this repository, without relying on external repositories? Thanks.

Member

probonopd commented Apr 8, 2017

@darealshinji can you send a PR that incorporates this in a way it builds everyhting inside this repository, without relying on external repositories? Thanks.

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 9, 2017

Contributor

@probonopd Due to the bloated build system of gcc building the gcc runtimes takes relatively long. I think a good solution would be to put the build script and the .travis.yml file on a separate branch, so that the build doesn't get triggered on every little commit. I don't think I can crate a PR for a new separate branch, but I could fork this repository (or probonopd/AppImageKit?) and setup and test everything. You will need to manually merge things then. Or maybe you create a new empty branch that I can make such a PR for.

Contributor

darealshinji commented Apr 9, 2017

@probonopd Due to the bloated build system of gcc building the gcc runtimes takes relatively long. I think a good solution would be to put the build script and the .travis.yml file on a separate branch, so that the build doesn't get triggered on every little commit. I don't think I can crate a PR for a new separate branch, but I could fork this repository (or probonopd/AppImageKit?) and setup and test everything. You will need to manually merge things then. Or maybe you create a new empty branch that I can make such a PR for.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 9, 2017

Member

We already build AppImageKit in a similar system, would it be easier to integrate it there?

Member

probonopd commented Apr 9, 2017

We already build AppImageKit in a similar system, would it be easier to integrate it there?

@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 9, 2017

In my scenario I don't need gcc to be built

In my adaptation of your system (@darealshinji) I stripped down your build script to only build the elf and testrt stuff since I am happy to supply the libstdc++ from my own 5.4.0 build of gcc.

Not sure if that is something to factor into your discussions...

oviano commented Apr 9, 2017

In my scenario I don't need gcc to be built

In my adaptation of your system (@darealshinji) I stripped down your build script to only build the elf and testrt stuff since I am happy to supply the libstdc++ from my own 5.4.0 build of gcc.

Not sure if that is something to factor into your discussions...

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 9, 2017

Contributor

@probonopd Probably. But what I'm trying to say is that the build takes long, about 17 minutes. That's because in order to build libgcc the actual gcc compilers and drivers need to be built first. If that's no problem for you I can try to integrate the build there.

@oviano The question would be how to automatically add the home-brew libraries and not accidentally the outdated system ones. That's the main reason why I'm struggling here with building it from source.

Contributor

darealshinji commented Apr 9, 2017

@probonopd Probably. But what I'm trying to say is that the build takes long, about 17 minutes. That's because in order to build libgcc the actual gcc compilers and drivers need to be built first. If that's no problem for you I can try to integrate the build there.

@oviano The question would be how to automatically add the home-brew libraries and not accidentally the outdated system ones. That's the main reason why I'm struggling here with building it from source.

@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 9, 2017

Could you not just make it a manual step for someone wanting this functionality - for example, if the app image tool sees a folder named "optional" (or something) in the AppDir then it looks in here for the libstdc++ and libgcc and does the magic?

Sorry if I'm misunderstanding how things work.

oviano commented Apr 9, 2017

Could you not just make it a manual step for someone wanting this functionality - for example, if the app image tool sees a folder named "optional" (or something) in the AppDir then it looks in here for the libstdc++ and libgcc and does the magic?

Sorry if I'm misunderstanding how things work.

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 9, 2017

Contributor

@oviano Sounds interesting, will investigate it.

Contributor

darealshinji commented Apr 9, 2017

@oviano Sounds interesting, will investigate it.

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 9, 2017

Contributor

Here's a patch for AppRun.c. It will check if the script testrt.sh exists and execute it if it does. LD_LIBRARY_PATH will then be modified depending on the script's return value.

--- a/AppRun.c
+++ b/AppRun.c
@@ -146,12 +146,31 @@ int main(int argc, char *argv[]) {
     outargptrs[outargindex] = '\0';     // trailing null argument required by execvp()
 
     // change directory
-    char usr_in_appdir[1024];
+    const PATH_LENGTH = 1024;
+    char usr_in_appdir[PATH_LENGTH];
     sprintf(usr_in_appdir, "%s/usr", appdir);
     ret = chdir(usr_in_appdir);
     if (ret != 0)
         die("Could not cd into %s\n", usr_in_appdir);
 
+    // check if newer GCC runtimes are required
+    char optional[PATH_LENGTH];
+    if (access("./optional/testrt.sh", F_OK) == 0) {
+        char testrt_line[LINE_SIZE];
+        FILE *testrt_file = popen("sh ./optional/testrt.sh ; printf $?", "r");
+        fscanf(testrt_file, "%s", testrt_line);
+        pclose(testrt_file);
+        if (strlen(testrt_line) == 1) {
+            if (testrt_line[0] == '1') {
+                sprintf(optional, "%s/usr/optional/libstdc++/:", appdir);
+            } else if (testrt_line[0] == '2') {
+                sprintf(optional, "%s/usr/optional/libgcc_s/:", appdir);
+            } else if (testrt_line[0] == '3') {
+                sprintf(optional, "%s/usr/optional/libgcc_s/:%s/usr/optional/libstdc++/:", appdir);
+            }
+        }
+    }
+
     // set environment variables
     char *old_env;
     const LENGTH = 2047;
@@ -165,7 +184,7 @@ int main(int argc, char *argv[]) {
     snprintf(new_env[1], LENGTH, "PATH=%s/usr/bin/:%s/usr/sbin/:%s/usr/games/:%s/bin/:%s/sbin/:%s", appdir, appdir, appdir, appdir, appdir, old_env);
 
     old_env = getenv("LD_LIBRARY_PATH") ?: "";
-    snprintf(new_env[2], LENGTH, "LD_LIBRARY_PATH=%s/usr/lib/:%s/usr/lib/i386-linux-gnu/:%s/usr/lib/x86_64-linux-gnu/:%s/usr/lib32/:%s/usr/lib64/:%s/lib/:%s/lib/i386-linux-gnu/:%s/lib/x86_64-linux-gnu/:%s/lib32/:%s/lib64/:%s", appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, old_env);
+    snprintf(new_env[2], LENGTH, "LD_LIBRARY_PATH=%s%s/usr/lib/:%s/usr/lib/i386-linux-gnu/:%s/usr/lib/x86_64-linux-gnu/:%s/usr/lib32/:%s/usr/lib64/:%s/lib/:%s/lib/i386-linux-gnu/:%s/lib/x86_64-linux-gnu/:%s/lib32/:%s/lib64/:%s", optional, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, old_env);
 
     old_env = getenv("PYTHONPATH") ?: "";
     snprintf(new_env[3], LENGTH, "PYTHONPATH=%s/usr/share/pyshared/:%s", appdir, old_env);

testrt.sh:

#!/bin/sh

# Arrange files inside AppDir like this:
#  <APPDIR>/usr/optional/libgcc_s/libgcc_s.so.1
#  <APPDIR>/usr/optional/libstdc++/libstdc++.so.6
#  <APPDIR>/usr/optional/readelf
#  <APPDIR>/usr/optional/testrt
#  <APPDIR>/usr/optional/testrt.sh

LANG=C

ret_cxx=1
ret_gcc=2
ret_cxxgcc=3
ret_none=0
need_cxx_newer="no"
need_gcc_newer="no"

cxx_lib_system=$(ldd ./optional/testrt | grep libstdc++.so.6 | awk '{print $3}')
cxx_lib_bundle="./optional/libstdc++/libstdc++.so.6"
cxx_system=$(./optional/readelf -s $cxx_lib_system | grep -Eo '@GLIBCXX_[0-9.]{1,}' | sort --version-sort -r | sed -n 's/@GLIBCXX_//g; 1p')
cxx_bundle=$(./optional/readelf -s $cxx_lib_bundle | grep -Eo '@GLIBCXX_[0-9.]{1,}' | sort --version-sort -r | sed -n 's/@GLIBCXX_//g; 1p')
cxx_newer=$(echo "$cxx_bundle\n$cxx_system" | sort -V | tail -n1)

gcc_lib_system=$(ldd ./optional/testrt | grep libgcc_s.so.1 | awk '{print $3}')
gcc_lib_bundle="./optional/libgcc_s/libgcc_s.so.1"
gcc_system=$(./optional/readelf -s $cxx_lib_system | grep -Eo '@GCC_[0-9.]{1,}' | sort --version-sort -r | sed -n 's/@GCC_//g; 1p')
gcc_bundle=$(./optional/readelf -s $cxx_lib_bundle | grep -Eo '@GCC_[0-9.]{1,}' | sort --version-sort -r | sed -n 's/@GCC_//g; 1p')
gcc_newer=$(echo "$gcc_bundle\n$gcc_system" | sort -V | tail -n1)

if [ $cxx_bundle = $cxx_newer ] && [ $cxx_system != $cxx_bundle ] ; then
  need_cxx_newer="yes"
fi
if [ $gcc_bundle = $gcc_newer ] && [ $gcc_system != $gcc_bundle ] ; then
  need_gcc_newer="yes"
fi

if [ "$need_cxx_newer" = "yes" ] && [ "$need_gcc_newer" = "no" ] ; then
  exit $ret_cxx
elif [ "$need_cxx_newer" = "no" ] && [ "$need_gcc_newer" = "yes" ] ; then
  exit $ret_gcc
elif [ "$need_cxx_newer" = "yes" ] && [ "$need_gcc_newer" = "yes" ] ; then
  exit $ret_cxxgcc
fi

exit $ret_none
Contributor

darealshinji commented Apr 9, 2017

Here's a patch for AppRun.c. It will check if the script testrt.sh exists and execute it if it does. LD_LIBRARY_PATH will then be modified depending on the script's return value.

--- a/AppRun.c
+++ b/AppRun.c
@@ -146,12 +146,31 @@ int main(int argc, char *argv[]) {
     outargptrs[outargindex] = '\0';     // trailing null argument required by execvp()
 
     // change directory
-    char usr_in_appdir[1024];
+    const PATH_LENGTH = 1024;
+    char usr_in_appdir[PATH_LENGTH];
     sprintf(usr_in_appdir, "%s/usr", appdir);
     ret = chdir(usr_in_appdir);
     if (ret != 0)
         die("Could not cd into %s\n", usr_in_appdir);
 
+    // check if newer GCC runtimes are required
+    char optional[PATH_LENGTH];
+    if (access("./optional/testrt.sh", F_OK) == 0) {
+        char testrt_line[LINE_SIZE];
+        FILE *testrt_file = popen("sh ./optional/testrt.sh ; printf $?", "r");
+        fscanf(testrt_file, "%s", testrt_line);
+        pclose(testrt_file);
+        if (strlen(testrt_line) == 1) {
+            if (testrt_line[0] == '1') {
+                sprintf(optional, "%s/usr/optional/libstdc++/:", appdir);
+            } else if (testrt_line[0] == '2') {
+                sprintf(optional, "%s/usr/optional/libgcc_s/:", appdir);
+            } else if (testrt_line[0] == '3') {
+                sprintf(optional, "%s/usr/optional/libgcc_s/:%s/usr/optional/libstdc++/:", appdir);
+            }
+        }
+    }
+
     // set environment variables
     char *old_env;
     const LENGTH = 2047;
@@ -165,7 +184,7 @@ int main(int argc, char *argv[]) {
     snprintf(new_env[1], LENGTH, "PATH=%s/usr/bin/:%s/usr/sbin/:%s/usr/games/:%s/bin/:%s/sbin/:%s", appdir, appdir, appdir, appdir, appdir, old_env);
 
     old_env = getenv("LD_LIBRARY_PATH") ?: "";
-    snprintf(new_env[2], LENGTH, "LD_LIBRARY_PATH=%s/usr/lib/:%s/usr/lib/i386-linux-gnu/:%s/usr/lib/x86_64-linux-gnu/:%s/usr/lib32/:%s/usr/lib64/:%s/lib/:%s/lib/i386-linux-gnu/:%s/lib/x86_64-linux-gnu/:%s/lib32/:%s/lib64/:%s", appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, old_env);
+    snprintf(new_env[2], LENGTH, "LD_LIBRARY_PATH=%s%s/usr/lib/:%s/usr/lib/i386-linux-gnu/:%s/usr/lib/x86_64-linux-gnu/:%s/usr/lib32/:%s/usr/lib64/:%s/lib/:%s/lib/i386-linux-gnu/:%s/lib/x86_64-linux-gnu/:%s/lib32/:%s/lib64/:%s", optional, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, old_env);
 
     old_env = getenv("PYTHONPATH") ?: "";
     snprintf(new_env[3], LENGTH, "PYTHONPATH=%s/usr/share/pyshared/:%s", appdir, old_env);

testrt.sh:

#!/bin/sh

# Arrange files inside AppDir like this:
#  <APPDIR>/usr/optional/libgcc_s/libgcc_s.so.1
#  <APPDIR>/usr/optional/libstdc++/libstdc++.so.6
#  <APPDIR>/usr/optional/readelf
#  <APPDIR>/usr/optional/testrt
#  <APPDIR>/usr/optional/testrt.sh

LANG=C

ret_cxx=1
ret_gcc=2
ret_cxxgcc=3
ret_none=0
need_cxx_newer="no"
need_gcc_newer="no"

cxx_lib_system=$(ldd ./optional/testrt | grep libstdc++.so.6 | awk '{print $3}')
cxx_lib_bundle="./optional/libstdc++/libstdc++.so.6"
cxx_system=$(./optional/readelf -s $cxx_lib_system | grep -Eo '@GLIBCXX_[0-9.]{1,}' | sort --version-sort -r | sed -n 's/@GLIBCXX_//g; 1p')
cxx_bundle=$(./optional/readelf -s $cxx_lib_bundle | grep -Eo '@GLIBCXX_[0-9.]{1,}' | sort --version-sort -r | sed -n 's/@GLIBCXX_//g; 1p')
cxx_newer=$(echo "$cxx_bundle\n$cxx_system" | sort -V | tail -n1)

gcc_lib_system=$(ldd ./optional/testrt | grep libgcc_s.so.1 | awk '{print $3}')
gcc_lib_bundle="./optional/libgcc_s/libgcc_s.so.1"
gcc_system=$(./optional/readelf -s $cxx_lib_system | grep -Eo '@GCC_[0-9.]{1,}' | sort --version-sort -r | sed -n 's/@GCC_//g; 1p')
gcc_bundle=$(./optional/readelf -s $cxx_lib_bundle | grep -Eo '@GCC_[0-9.]{1,}' | sort --version-sort -r | sed -n 's/@GCC_//g; 1p')
gcc_newer=$(echo "$gcc_bundle\n$gcc_system" | sort -V | tail -n1)

if [ $cxx_bundle = $cxx_newer ] && [ $cxx_system != $cxx_bundle ] ; then
  need_cxx_newer="yes"
fi
if [ $gcc_bundle = $gcc_newer ] && [ $gcc_system != $gcc_bundle ] ; then
  need_gcc_newer="yes"
fi

if [ "$need_cxx_newer" = "yes" ] && [ "$need_gcc_newer" = "no" ] ; then
  exit $ret_cxx
elif [ "$need_cxx_newer" = "no" ] && [ "$need_gcc_newer" = "yes" ] ; then
  exit $ret_gcc
elif [ "$need_cxx_newer" = "yes" ] && [ "$need_gcc_newer" = "yes" ] ; then
  exit $ret_cxxgcc
fi

exit $ret_none
@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 9, 2017

Yes, this is exactly what I had in mind. Adds the functionality in a flexible manner while keeping it optional.

I think you need to initialise the optional string however, as if the testrt.sh script does not exist then it may contain garbage depending on the platform, compiler etc.

oviano commented Apr 9, 2017

Yes, this is exactly what I had in mind. Adds the functionality in a flexible manner while keeping it optional.

I think you need to initialise the optional string however, as if the testrt.sh script does not exist then it may contain garbage depending on the platform, compiler etc.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 10, 2017

Member

@darealshinji why do you need to build your own compiler and cannot use the one from the devtoolkit on CentOS 6?
And, how hard would it be to implement this in C?

Member

probonopd commented Apr 10, 2017

@darealshinji why do you need to build your own compiler and cannot use the one from the devtoolkit on CentOS 6?
And, how hard would it be to implement this in C?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 10, 2017

Contributor

I've updated the C part of my PR: AppImage/AppImageKit#379
Doing everything that the testrt.sh script does in C would require to mess around with libelf or a similar library. How hard that is... I don't know.

Contributor

darealshinji commented Apr 10, 2017

I've updated the C part of my PR: AppImage/AppImageKit#379
Doing everything that the testrt.sh script does in C would require to mess around with libelf or a similar library. How hard that is... I don't know.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 10, 2017

Member

I am not sure if introducing bash to AppRun.c should be the way to go. If you introduce bash as a runtime dependency, then why not use your own AppRun bash script in the first place?

Member

probonopd commented Apr 10, 2017

I am not sure if introducing bash to AppRun.c should be the way to go. If you introduce bash as a runtime dependency, then why not use your own AppRun bash script in the first place?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 10, 2017

Contributor

The script doesn't need /bin/bash, it runs on /bin/sh which is present on any POSIX system. I could try to hack readelf.c and see if I can use it as a function from within AppRun, but the binary will grow a lot if you don't remove unneeded stuff from readelf.c.

Contributor

darealshinji commented Apr 10, 2017

The script doesn't need /bin/bash, it runs on /bin/sh which is present on any POSIX system. I could try to hack readelf.c and see if I can use it as a function from within AppRun, but the binary will grow a lot if you don't remove unneeded stuff from readelf.c.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 10, 2017

Member

Nah, don't think we should do that, in fact we made AppRun.c as small as reasonably possible. In fact given all your information about building and using this I think this would better live in its own repository and not have any hooks inside AppImageKit, and use its own custom AppRun sh script. This way, it is most flexible and entirely decoupled from AppImageKit core development. Do you agree?

Member

probonopd commented Apr 10, 2017

Nah, don't think we should do that, in fact we made AppRun.c as small as reasonably possible. In fact given all your information about building and using this I think this would better live in its own repository and not have any hooks inside AppImageKit, and use its own custom AppRun sh script. This way, it is most flexible and entirely decoupled from AppImageKit core development. Do you agree?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 11, 2017

Contributor

Well, it's only about 25 lines additional code added to AppRun.c which will only be used when <APPDIR>/usr/optional/testrt.sh was found.

Contributor

darealshinji commented Apr 11, 2017

Well, it's only about 25 lines additional code added to AppRun.c which will only be used when <APPDIR>/usr/optional/testrt.sh was found.

@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 11, 2017

I agree, I think that is a little disappointing.

I thought it fitted well into the project.

Oh well.

oviano commented Apr 11, 2017

I agree, I think that is a little disappointing.

I thought it fitted well into the project.

Oh well.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 11, 2017

Member

The point is, if we use a bash script, then we can put the functionality of AppRun.c into that bash script as well. @darealshinji @oviano do you see reasons to still add this code to the default AppRun.c, given that probably >98% of AppImages will not have a testrt.sh file? Don't get me wrong, I really like this contribution and I think it is very valuable, I just think we should keep things as lean as possible for the majority of cases, and do allow for the special case (e.g., by using a custom AppRun bash script).

Member

probonopd commented Apr 11, 2017

The point is, if we use a bash script, then we can put the functionality of AppRun.c into that bash script as well. @darealshinji @oviano do you see reasons to still add this code to the default AppRun.c, given that probably >98% of AppImages will not have a testrt.sh file? Don't get me wrong, I really like this contribution and I think it is very valuable, I just think we should keep things as lean as possible for the majority of cases, and do allow for the special case (e.g., by using a custom AppRun bash script).

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 11, 2017

Contributor

I'm trying to build a patched AppRun binary for people who need it, but the Travis builds are failing at squashfuse because of the stupid autotools: https://github.com/darealshinji/AppImage-gcc-runtime/commits/master
@probonopd maybe you can help me with it? Can't you use the tarball from the release section https://github.com/vasi/squashfuse/releases ? That has all the files generated by the autotools.

Contributor

darealshinji commented Apr 11, 2017

I'm trying to build a patched AppRun binary for people who need it, but the Travis builds are failing at squashfuse because of the stupid autotools: https://github.com/darealshinji/AppImage-gcc-runtime/commits/master
@probonopd maybe you can help me with it? Can't you use the tarball from the release section https://github.com/vasi/squashfuse/releases ? That has all the files generated by the autotools.

@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 12, 2017

@probonopd I do understand what you are saying.

If I understand correctly that would mean that there would be two AppRuns to maintain - the official one, and then any enhancements that you might make to that would have to be manually ported to the bash script version?

To me that would seem a little bit messy - what about just making @darealshinji's new feature a conditional compilation so at least people could download your latest source and compile it themselves using an extra flag or something? The default build would exclude it but at least the code would exist in AppRun.c and therefore any other changes and improvements you make to AppRun would then be available to everybody.

oviano commented Apr 12, 2017

@probonopd I do understand what you are saying.

If I understand correctly that would mean that there would be two AppRuns to maintain - the official one, and then any enhancements that you might make to that would have to be manually ported to the bash script version?

To me that would seem a little bit messy - what about just making @darealshinji's new feature a conditional compilation so at least people could download your latest source and compile it themselves using an extra flag or something? The default build would exclude it but at least the code would exist in AppRun.c and therefore any other changes and improvements you make to AppRun would then be available to everybody.

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 12, 2017

Contributor

Just a little heads-up: I think I may be able to skip the need for the testrt binary and testrt.sh script.

Contributor

darealshinji commented Apr 12, 2017

Just a little heads-up: I think I may be able to skip the need for the testrt binary and testrt.sh script.

@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 12, 2017

Sounds promising, what is your thinking?

oviano commented Apr 12, 2017

Sounds promising, what is your thinking?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 12, 2017

Contributor

I can use tr, grep and tail to get the symbols from the libraries and compare them using C functions. I just need to find a good way to locate the default system libraries, maybe just scan through the typical system library paths until I find something.

  int ret;
  FILE *f;
  char command[512];

  char *stdcxx_sys_lib = "/usr/lib/x86_64-linux-gnu/libstdc++.so.6";
  sprintf(command, "tr '\\0' '\\n' < '%s' | grep -e '%s' | tail -n1", stdcxx_sys_lib, "^GLIBCXX_3\\.4");

  char stdcxx_sys_sym[32];
  f = popen(command, "r");
  fscanf(f, "%s", stdcxx_sys_sym);
  pclose(f);

  printf("%s ==> %s\n", stdcxx_sys_lib, stdcxx_sys_sym);
Contributor

darealshinji commented Apr 12, 2017

I can use tr, grep and tail to get the symbols from the libraries and compare them using C functions. I just need to find a good way to locate the default system libraries, maybe just scan through the typical system library paths until I find something.

  int ret;
  FILE *f;
  char command[512];

  char *stdcxx_sys_lib = "/usr/lib/x86_64-linux-gnu/libstdc++.so.6";
  sprintf(command, "tr '\\0' '\\n' < '%s' | grep -e '%s' | tail -n1", stdcxx_sys_lib, "^GLIBCXX_3\\.4");

  char stdcxx_sys_sym[32];
  f = popen(command, "r");
  fscanf(f, "%s", stdcxx_sys_sym);
  pclose(f);

  printf("%s ==> %s\n", stdcxx_sys_lib, stdcxx_sys_sym);
@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 12, 2017

I can see the upside, but isn't the concern that whatever your method for finding the system libraries it won't be as reliable as testrt?

oviano commented Apr 12, 2017

I can see the upside, but isn't the concern that whatever your method for finding the system libraries it won't be as reliable as testrt?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 12, 2017

Contributor

Using ldconfig should to the trick:

ldconfig -p | grep 'libstdc++.so.6 (libc6)' | awk 'NR==1{print $NF}'  #i386
ldconfig -p | grep 'libstdc++.so.6 (libc6,x86-64)' | awk 'NR==1{print $NF}'  #x86_64
Contributor

darealshinji commented Apr 12, 2017

Using ldconfig should to the trick:

ldconfig -p | grep 'libstdc++.so.6 (libc6)' | awk 'NR==1{print $NF}'  #i386
ldconfig -p | grep 'libstdc++.so.6 (libc6,x86-64)' | awk 'NR==1{print $NF}'  #x86_64
@oviano

This comment has been minimized.

Show comment
Hide comment
@oviano

oviano Apr 12, 2017

Fair enough, I can safely say you know more about this than I do :)

oviano commented Apr 12, 2017

Fair enough, I can safely say you know more about this than I do :)

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 12, 2017

Contributor

I still had to do my research to find this solution. Anyway, here's my code: https://gist.github.com/darealshinji/588f31f828e79284f1e77b5fe79f8c3c

Returns this for me:

$ gcc -Wall -O2 test.c && ./a.out
/usr/lib/x86_64-linux-gnu/libstdc++.so.6 ==> GLIBCXX_3.4.21 (21)
./optional/libstdc++/libstdc++.so.6 ==> GLIBCXX_3.4.16 (16)

/lib/x86_64-linux-gnu/libgcc_s.so.1 ==> GCC_4.8.0 (480)
./optional/libgcc/libgcc_s.so.1 ==> GCC_4.3.0 (430)

using system libstdc++.so.6
using system libgcc_s.so.1
Contributor

darealshinji commented Apr 12, 2017

I still had to do my research to find this solution. Anyway, here's my code: https://gist.github.com/darealshinji/588f31f828e79284f1e77b5fe79f8c3c

Returns this for me:

$ gcc -Wall -O2 test.c && ./a.out
/usr/lib/x86_64-linux-gnu/libstdc++.so.6 ==> GLIBCXX_3.4.21 (21)
./optional/libstdc++/libstdc++.so.6 ==> GLIBCXX_3.4.16 (16)

/lib/x86_64-linux-gnu/libgcc_s.so.1 ==> GCC_4.8.0 (480)
./optional/libgcc/libgcc_s.so.1 ==> GCC_4.3.0 (430)

using system libstdc++.so.6
using system libgcc_s.so.1
@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 12, 2017

Member

@darealshinji how hard, how useful would it be to expand this concept so that it could generically be applied to random libraries rather than just libgcc_s and libstdc++?

Member

probonopd commented Apr 12, 2017

@darealshinji how hard, how useful would it be to expand this concept so that it could generically be applied to random libraries rather than just libgcc_s and libstdc++?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 13, 2017

Contributor

@probonopd I don't know. Using grep to get the library version from its symbols is reliable on libgcc and libstdc++, but I don't know about other libraries. That may require further testing. Do you have any other libraries in mind where to apply such a check at runtime?

edit:

This doesn't seem to work generally on libraries. But I guess you could dlopen() a library and use a version function, if the library provides that.

Contributor

darealshinji commented Apr 13, 2017

@probonopd I don't know. Using grep to get the library version from its symbols is reliable on libgcc and libstdc++, but I don't know about other libraries. That may require further testing. Do you have any other libraries in mind where to apply such a check at runtime?

edit:

This doesn't seem to work generally on libraries. But I guess you could dlopen() a library and use a version function, if the library provides that.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd Apr 15, 2017

Member

@darealshinji the https://gist.github.com/darealshinji/588f31f828e79284f1e77b5fe79f8c3c doesn't seem to use bash anymore which I like very much. Can you make an AppRun.c based on this, and put that into its own repository? If you like, I would take this into the https://github.com/AppImage organization (where AppImageKit also will move) to make it more official.

Member

probonopd commented Apr 15, 2017

@darealshinji the https://gist.github.com/darealshinji/588f31f828e79284f1e77b5fe79f8c3c doesn't seem to use bash anymore which I like very much. Can you make an AppRun.c based on this, and put that into its own repository? If you like, I would take this into the https://github.com/AppImage organization (where AppImageKit also will move) to make it more official.

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji Apr 26, 2017

Contributor

@probonopd Sorry for not responding earlier.
Here's such a repo: https://github.com/darealshinji/AppImageKit-checkrt

Contributor

darealshinji commented Apr 26, 2017

@probonopd Sorry for not responding earlier.
Here's such a repo: https://github.com/darealshinji/AppImageKit-checkrt

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd May 3, 2017

Member

Thank you very much @darealshinji - would you be so kind and add a descriptive summary and a README.md? I would like to link to it from the AppImage wiki.

Member

probonopd commented May 3, 2017

Thank you very much @darealshinji - would you be so kind and add a descriptive summary and a README.md? I would like to link to it from the AppImage wiki.

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji May 4, 2017

Contributor

Description and README.md were added. Binaries built by TravisCI are in the release section.

Contributor

darealshinji commented May 4, 2017

Description and README.md were added. Binaries built by TravisCI are in the release section.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd May 4, 2017

Member

Thanks @darealshinji. So would you agree that instead of merging this PR we could mention your repository in the Wiki and README?

Member

probonopd commented May 4, 2017

Thanks @darealshinji. So would you agree that instead of merging this PR we could mention your repository in the Wiki and README?

@darealshinji

This comment has been minimized.

Show comment
Hide comment
@darealshinji

darealshinji May 5, 2017

Contributor

Sure, go ahead.

Contributor

darealshinji commented May 5, 2017

Sure, go ahead.

@probonopd

This comment has been minimized.

Show comment
Hide comment
@probonopd

probonopd May 6, 2017

Member

Added at Added a description at https://github.com/probonopd/AppImageKit/wiki/Creating-AppImages#libstdcso6, largely copied from the project description. Thank you very much for this project.

Member

probonopd commented May 6, 2017

Added at Added a description at https://github.com/probonopd/AppImageKit/wiki/Creating-AppImages#libstdcso6, largely copied from the project description. Thank you very much for this project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment