How to control the environment in which xmonad compiles user config? - xmonad

Xmonad architecture (as I understand it) allows the compiled executable trigger its own build system so that it can recompile itself and fork.
Does that mean that Xmonad (the desktop environment) must be run with environment appropriate for is build system? That would be unfortunate since all processes would inherit environment specific to building Xmonad.
This would kind-of make sense only if Xmonad used vanilla GHC environment provided by the OS.

If a script called build exists in the configuration directory (usually ~/.xmonad), Xmonad will call it when recompiling (usually triggered by M-q or xmonad --recompile) instead of invoking GHC directly. I suppose that script could construct any environment you want, do the build, and then deconstruct it if needed. Not sure if that's what you're looking for.

XMonad can be compiled to an executable and run without depending on GHC and it's build dependencies.
But yes if the recompilation is invoked it would probaly fail in the event that the necessary dependencies are not present.

Related

How to tell if configure and make support out-of-tree builds?

I often need to build common link libraries like zlib, libpng, jpeglib, freetype, etc. for many different architectures. I prefer to do out-of-tree builds then, like so:
mkdir build_linux_x64
cd build_linux_x64
../configure
make
This usually works fine but now I have read that this will only work if the following condition is met: "The project must be enabled for out-of-tree builds, typically with the user of VPATH if using make" (Source)
This leads me to the question: How can I tell if a project is enabled for out-of-tree builds? Will configure or make just fail if the project isn't enabled for out-of-tree builds or how should I tell?
If the out-of-tree build works, then you know it works :). When they say "enabled" they don't mean there's some switch or configuration option that the project has to turn on. They mean that the author of the package needs to have written their Makefile.am (or Makefile.in if they don't use automake) files to work correctly when run out-of-tree. There's no way to know whether these files are written correctly except by trying it out.
If you try it out and it doesn't work you should file a bug with the package.
Note that the standard method of creating source distribution packages with autotools forces the use of out-of-tree builds, so if they're creating their source distribution using the standard methods then it will definitely build out-of-tree correctly.

Set environmental vars and enable core dumps in autotools build

I am using Autotools for my current project. I'm using Ubuntu and Linux mint. With Autotools I can tell it to check a users's system to check for any required libraries my project needs in order to function properly. Now I would like to check if a user's system has enabled core dumps and if not, then execute the command ulimit -c unlimited to enable core dumps. How and where do I specify this?
Also, once the user has executed the make command to compile the source code, they execute sudo make install in order to move the binaries at /usr/local/bin/MYPROJECT. I want to add the location of my project's binaries into the path environmental variable, so that the user can execute any of the binaries in my project from a terminal without the need of typing the full path. How and where do I specify this in Autotools?
I'm thinking this is something I would add in the configure.ac file, but I haven't found any examples on how I can do this. Any help would be appreciated.
It sounds as if you basically misunderstand what installation of a software
package on Linux is about.
The job of autotools is to build a portable installation package of your
software. When I install your package, it does not become your decision
whether programs that crash will generate core dumps on my computer
when I run them. It does not become your decision what PATH I use to
invoke programs by unqualified name. These are my decisions or defaults
that I have accepted from my OS distribution.
If you execute ulimit -c unlimited, the command will in any case
only apply to the shell in which it is invoked. It doesn't
reconfigure the host system (!).
If you would like users to be able to invoke your program by unqualified
name, the normal procedure is make your package install it by default in the place,
/usr/local/bin, that unix-like OSes traditionally add to a
user's default PATH for finding locally installed programs. That is
where autotools will configure it to be installed, by default. Change it
only if you don't want your program to be in the user's default PATH.
And in any case, a user can decide where your software is installed by
passing --prefix=/path/of/my/choice to the ./configure command. Unless
you have some unavoidable reason not to, make your package installation
use the defaults that everybody expects and leave it up to the installing user
to change them.
Bottom line: You are asking how to do installation actions with autotools that
are not meant to be done with autotools, because they are not meant to be
done by package installations.

building a c++ project with customly built gcc(g++)

I have built gcc-4.8.2 from source code, configured with --prefix=.../destdir. I'm using Ubuntu 12.04 64-bit.
So after I ran 'make' and 'make install' all the libraries where built and put to
.../destdir/lib/gcc/x86_64-unknown-linux-gnu/4.8.2.
And I also have newly built g++ and gcc in
.../destdir/bin
the question is, if I try to build a program with .../destdir/bin/g++ will use the newly made libraries when linking, or the ones located in standard paths?
If latter, what is the best way to make it linkt against the new ones, or is there a way to know what libs are used?
By default it will use the right libraries at link time, but not at run time.
To use the right libraries at run time, either add -Wl,-rpath=/absolute/path/to/your/libraries to your link command (recommended), or add that directory to your $LD_LIBRARY_PATH (a quick-and-dirty workaround).

Moving a compiled Haskell program

I want to compile a Haskell program on one Linux box, and then run it on another Linux box. However, this doesn't seem to work at all. I get errors about missing libraries.
Presumably when I install GHC, the package manager also installs all the libraries and stuff that it needs. [I note with some irritation that at least one packaging system fails to install GCC, which GHC apparently can't function without...] But of course, the target system does not have these dependencies installed. So if I copy the compiled binary to the target system, it just fails to run.
Is there some way around this problem? I'm used to working with Windows, where if you compile something, it just works on all Windows systems. (At least, it does until you actually try to use non-standard facilities like database access or something...) I compiled Hello World in Haskell, copied it to another Linux box, and it complained about libgmp.so.10 missing or some cryptic mumbo-jumbo like that.
Just to make things interesting: I only have FTP access to the target machine, not shell access. I'm not even completely sure what OS it's running. So I can change my build machine any way I want, but I can't do anything to the target machine other than copy files to it.
Linux behaves just like Windows in this regard. If you compile a Haskell executable on Linux, it will run on any Linux distribution with the right libraries. The problem is that in Windows, the Haskell executables aren't compiled with a dynamic version of libgmp; they are compiled with a static version (so that the library is compiled into the executable) exactly because it can be so difficult to handle dlls on Windows when distributing executables. It is comparably easy to handle the installation of new libraries on Linux.
What you can do is to copy the libgmp.so.10 (which might be a symbolic link to a different file) out of /usr/lib into the same directory as your executable. You can then set the LD_LIBRARY_PATH environment variable to ".", meaning the current directory, before launching your executable. This will make Linux look for libraries in the same directory as executables that it launches, making it find the library. This can be done with a launcher script:
#!/bin/sh
export LD_LIBRARY_PATH=.
`dirname "$0"`/myexecutable "$#"
Saving this script and marking it as executable with chmod +x myscript will make your executable work.
You can use the ldd command to check what other libraries your executable might need and that aren't on the target system.
If you wish to move executable between machines, you have to link in statically, making single executable without external library dependencies. How to do it depends on compiler, and ghc has -static flag, that 'links static version of haskell libraries'.
btw, check, that you do not try to run 64-bit executable on 32 bit machine. 32-bit executable on 64 bit machine should work in most cases, but... well, it depends on configuration of target box, so check that this is not the case as well.

What's the accepted method for deploying a linux application that relies on shared libraries?

I have an application that relies on Qt, GDCM, and VTK, with the main build environment being Qt. All of these libraries are cross-platform and compile on Windows, Mac, and Linux. I need to deploy the application to Linux after deploying on Windows. The versions of vtk and gdcm I'm using are trunk versions from git (about a month old), more recent than what I can get apt-get on Ubuntu 11.04, which is my current (and only) Linux deployment target.
What is the accepted method for deploying an application that relies on these kinds of libraries?
Should I be statically linking here, to avoid LD_LIBRARY_PATH? I see conflicting reports on LD_LIBRARY_PATH; tutorials like this one suggest that it's the 'right way' to modify the library path to use shared libraries through system reboots. Others suggest that I should never set LD_LIBRARY_PATH. In the default version of GDCM, the installation already puts libraries into the /usr/local/lib directory, so those libraries get seen when I run ldd <my program>. VTK, on the other hand, puts its libraries into /usr/local/lib/vtk-5.9, which is not part of the LD_LIBRARY_PATH on most user's machines, and so is not found unless some change is made to the system. Copying the VTK files into '/usr/local/lib' does not allow 'ldd' to see the files.
So, how can I make my application see VTK to use the libraries?
On windows, deploying the dlls is very straightforward, because I can just include them in the installer, and the application finds them because they are in the local directory. That approach does not work in Linux, so I was going to have the users install Qt, GDCM, and VTK from whatever appropriate source and use the default locations, and then have the application point to those default locations. However, since VTK is putting things into a non-standard location, should I also expect users to modify LD_LIBRARY_PATH? Should I include the specific versions of the libraries that I want and then figure out how to make the executable look in the local directory for those libraries and ignore the ones it finds in the library path?
Every "serious" commercial application I have ever seen uses LD_LIBRARY_PATH. They invariably include a shell script that looks something like this:
#!/bin/sh
here="${0%/*}" # or you can use `dirname "$0"`
LD_LIBRARY_PATH="$here"/lib:"$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
exec "$0".bin "$#"
They name this script something like .wrapper and create a directory tree that looks like this:
.wrapper
lib/ (directory full of .so files)
app1 -> .wrapper (symlink)
app1.bin (executable)
app2 -> .wrapper (symlink)
app2.bin (executable)
Now you can copy this whole tree to wherever you want, and you can run "/path/to/tree/app1" or "/path/to/tree/app2 --with --some --arguments" and it will work. So will putting /path/to/tree in your PATH.
Incidentally, this is also how Firefox and Chrome do it, more or less.
Whoever told you not to use LD_LIBRARY_PATH is full of it, IMHO.
Which system libraries you want to put in lib depends on which Linux versions you want to officially support.
Do not even think about static linking. The glibc developers do not like it, they do not care about supporting it, and they somehow manage to break it a little harder with every release.
Good luck.
In general, you're best off depending on the 'normal' versions of the libraries for whatever distribution you're targetting (and saying you don't support dists that don't support recent enough versions of the lib), but if you REALLY need to depend on a bleeding edge version of some shared lib, you can link your app with -Wl,-rpath,'$ORIGIN' and then install a copy of the exact version you want in the same directory as your executable.
Note that if you use make, you'll need $$ in the makefile to get a single $ into the argument that is actually sent to the linker. The single qutoes are needed so the shell doesn't munge things...
Well, there are two options for deploying Linux application.
The correct way:
make a package for your app and for the libraries, if they are so special, that they can't be installed from standard repositories
There are two major package formats. RPM and DEB.
The easy way:
make a self-extract file that will install the "windows way" into /opt.
You can have libraries in the same directory as the executable, it's just not the preferred way.

Resources