Set environmental vars and enable core dumps in autotools build - linux

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.

Related

Installing dependencies in configure script

I'm writing a program that requires LLVM, and thinking of using autotools to ship it on Linux, so from the user's viewpoint the process would look like the well-known ./configure && make && sudo make install.
With autotools, one normally relies on the system package manager to install dependencies. The problem is that, for whatever reason, this doesn't work with LLVM; on Ubuntu 14.04, apt-get thinks the latest version is 3.4, whereas a more recent version would actually be needed. Thus, I need to supply a script to download and build LLVM first (a local copy thereof, not interfering with any older version that might be on the system), a process which takes a few hours.
The most obvious place to put this process is at the start of configure. Is this considered normal and reasonable? Or is there a convention that configure should only contain the things autotools normally puts in it, and installing dependencies should be another script that the user runs first and separately? In the latter case, is there a convention regarding what that separate script should be called?
Don't install anything during configure. The scripts name is "configure" not "install-dependencies".
Write a configure check, and if llvm is missing, Give the user an explanation how to install it. If necessary provide a separate script to download llvm.
It is good practice to run configure (and make) as normal unprivileged user and not as root. So you may not even have permissions to install anything. You would have to check if "sudo" is installed, etc.
It may also happen that the system the user is installing has no network connectivity (firewall etc.), so your download will fail.

How to automake installation process on Linux-like operating systems?

I wrote a simple C application but it has some dependencies. Instead of giving my friend (who is a linux noob) commands to run in terminal, to install the dependencies, I would like to give him a single file that would install everything my application needs.
Btw, is makefile a good idea, or maybe a bash script would be most appropriate? I would like to ask about the root password only once, save it somewhere (in the script/makefile variable) and then simply use it to install all dependencies. Any ideas how to do it the most professional way?
This is what packages are for.
Depending on what target OS/distribution, you will need to package a DEB or an RPM.
There are tools to simplify this process that allow declaring dependencies as well as running pre/post install/uninstall scripts.
The most professional way to distribute this is using a private repository.

What is the significance of the location of the files of an installed program on Linux?

Once a program is installed in Linux, sometimes I find out that it is easier to put in a different location. In general, what is the significance of the location of the files of an installed program on Linux?
Often the advice on the internet is to add the (wrong or inconvenient) paths to environment variables. I'd much rather move the files to locations where they are automatically found by commands and programs.
One recent example is site-packages of Python. My Python did not appear to check the PYTHONPATH variable, moving the libraries there to the Python2.7/ directory worked well.
Now Ia m facing the same issue with OpenCV.
I also wonder why Linux installation does not prompt (like Windows) for the desired installation directory and why, so often, things wind up in places where they don't work?
In general, programs are installed in /usr/bin (for binaries) and /usr/lib, or a specific path to that specific linux distro, so that any program that you install that uses a specific library/program will search in that path for it. If you install a program in a different path, let's say /home/user/program, it will be installed locally and other programs won't be able by default to access it.
You can install any program wherever you want. However, it is good use to use the repo and install them in the general path.
I don't know how you install programs, but I use apt-get and dpkg on Ubuntu. You can also install some python modules this way.
Generally you are supposed to use the package system provided by your distro (IMHO).
If you do not use packages then you are on your own.
About PYTHONPATH. Did you add it to your .bashrc and made sure that it was set in the terminal you are using?
Also please see:
http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

Linux capabilities (setcap) seems to disable LD_LIBRARY_PATH

I use LD_LIBRARY_PATH to set the path of a certain user library for an application. But if I set capabilities on this application
sudo setcap CAP_NET_BIND_SERVICE=eip myapplication
then LD_LIBRARY_PATH seems to be ignored. When I launch the program, Linux complains that it cannot find a certain shared library.
I guess that there's some kind of protection kicking in, to prevent applications with extended rights from being hijacked. Is there a workaround?
As already stated in other answers, this behavior is intended. There is some kind of workaround if you can compile (or at least link) the application yourself. Then you can pass -Wl,-rpath <yourDynamicLibraryPath> to gcc or -rpath <yourDynamicLibraryPath> to ld and you won't have to specify LD_LIBRARY_PATH at all on execution.
The solution to this problem on linux is as follows:
go to directory
$cd /etc/ld.so.conf.d/
create a new file
$touch xyz.conf
open this file using any editor
$vi xyz.conf
Add the your dynamic library path in this file line by line for e.g. if your path is as follows:
/home/xyz/libs1:/home/xyz/libs2/:/home/xyz/libs3/
then there should be three entries in this file as follows:
/home/xyz/libs1/
/home/xyz/libs2/
/home/xyz/libs3/
Then save this file and execute the following command:
$ldconfig
All the above mentioned operation need to be performed from root login
The man page for sudo explains:
Note that the dynamic linker on most operating systems will remove
variables that can control dynamic linking from the environment of
setuid executables, including sudo. Depending on the operating system
this may include RLD*, DYLD*, LD_, LDR_, LIBPATH, SHLIB_PATH, and
others. These type of variables are removed from the environment
before sudo even begins execution and, as such, it is not possible for
sudo to preserve them.
As this link explains, the actual mechanism for doing this is in glibc. If the UID does not match the EUID (which is the case for any setuid program, including sudo), then all "unsecure environment variables" are removed. Thus, a program with elevated privileges runs without alteration.
Yes, it's disabled for security reasons.
An alternative to consider is to "correct" a poorly compiled ELF shared library and/or executable using patchelf to set the rpath.
https://nixos.org/patchelf.html
ld.so.conf is not always the sure bet. It will work if whatever you are running was compiled properly. In my case, with a particular specially packaged vendor's apache product, it was compiled so poorly: They did not even use unique .so filenames so they conflicted with .so filenames from RPMs in the base RHEL repositories that provided some pretty critical commonly used libraries. So this was the only option to isolate how they were used. Using ld.so.conf against those shared objects in the vendor's lib path would have blown away a lot of stuff, that included yum, along with glibc shared library failures, system-wide.

What should Linux/Unix 'make install' consist of?

I've written a C++ program (command line, portable code) and I'm trying to release a Linux version at the same time as the Windows version. I've written a makefile as follows:
ayane: *.cpp *.h
g++ -Wno-write-strings -oayane *.cpp
Straightforward enough so far; but I'm given to understand it's customary to have a second step, make install. So when I put the install: target in the makefile... what command should be associated with it? (If possible I'd prefer it to work on all Unix systems as well as Linux.)
Installation
A less trivial installer will copy several things into place, first insuring that the appropriate paths exists (using mkdir -p or similar). Typically something like this:
the executable goes in $INSTALL_PATH/bin
any libraries built for external consumption go in $INSTALL_PATH/lib or $INSTALL_PATH/lib/yourappname
man pages go in $INSTALL_PATH/share/man/man1 and possibly other sections if appropriate
other docs go in $INSTALL_PATH/share/yourappname
default configuration files go in $INSTALL_PATH/etc/yourappname
headers for other to link against go in $INSTALL_PATH/include/yourappname
Installation path
The INSTALL_PATH is an input to the build system, and usually defaults to /usr/local. This gives your user the flexibility to install under their $HOME without needing elevated permission.
In the simplest case just use
INSTALL_PATH?=/usr/local
at the top of the makefile. Then the user can override it by setting an environment variable in their shell.
Deinstallation
You also occasionally see make installs that build a manifest to help with de-installation. The manifest can even be written as a script to do the work.
Another approach is just to have a make uninstall that looks for the things make install places, and removes them if they exist.
In the simplest case you just copy the newly created executable into the /usr/local/bin path. Of course, it's usually more complicated than that.
Notice that most of these operations require special rights, which is why make install is usually invoked using sudo.
make install is usually the step that "installs" the binary into the correct place.
For example, when compiling Vim, make install may place it in /usr/local/bin
Not all Makefiles have a make install

Resources