How to add include and lib paths to configure/make cycle?
I need a place to install libraries in a linux box I have no su access to. I’m using ~/local[/bin,/lib,/include], but I don’t know how can I tell ./configure to look for libraries there (particularly, I’m trying to compile emacs, which needs libgif, which doesn’t come in my distro). I tried adding
export PATH=$PATH:~/local/bin export LD_LIBRARY_PATH=~/local/lib export C_INCLUDE_PATH=~/local/include export CPLUS_INCLUDE_PATH=~/local/include
Note that excepted for the PATH, you overwrite your system default ones. If you make something like export C_INCLUDE_PATH=~/local/include:$C_INCLUDE_PATH , your compiler will search firstly in ~/local/include , and in $C_INCLUDE_PATH only if it didn’t found the include in the first directory.
6 Answers 6
You want a config.site file. Try:
$ mkdir -p ~/local/share $ cat ~/local/share/config.site CPPFLAGS=-I$HOME/local/include LDFLAGS=-L$HOME/local/lib . EOF
Whenever you invoke an autoconf generated configure script with —prefix=$HOME/local, the config.site will be read and all the assignments will be made for you. CPPFLAGS and LDFLAGS should be all you need, but you can make any other desired assignments as well (hence the . in the sample above). Note that -I flags belong in CPPFLAGS and not in CFLAGS, as -I is intended for the pre-processor and not the compiler.
William; A thanks, that was bang on advice about CPPFLAGS for building on a shared host. Saved much thrashing about with failed ./configure runs today, because of your note.
Set LDFLAGS and CFLAGS when you run make:
$ LDFLAGS="-L/home/me/local/lib" CFLAGS="-I/home/me/local/include" make
If you don’t want to do that a gazillion times, export these in your .bashrc (or your shell equivalent). Also set LD_LIBRARY_PATH to include /home/me/local/lib:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/me/local/lib
when I add LDFLAGS and CFLAGS to .bashrc ./configure fails with a configure: error: C compiler cannot create executables.
They are probably overriding the configure test code compiler parameters. Just use the make env prefetching. Also try and see if configure doesn’t already have an option for overriding libgif. If the autotools scripts are properly made it will alow you to spec a path where libgif is installed (e.g. override the default library location). That would be the cleaner solution.
same difference.. tneme@ws16lab07:~/Descargas/emacs-23.3$ LDFLAGS=»-L/home/tneme/local/lib» CFLAGS=»-l/home/tneme/local/include» ./configure —prefix=»/home/tneme/local» checking build system type. i686-pc-linux-gnu checking host system type. i686-pc-linux-gnu checking for gcc. gcc checking whether the C compiler works. no configure: error: in /home/tneme/Descargas/emacs-23.3′: configure: error: C compiler cannot create executables See config.log’ for more details t
just tried configuring emacs 23 with these and I didn’t get that problem: LDFLAGS=»-L/home/me/local/lib» CFLAGS=»-I/home/me/local/include» ./configure checking build system type. x86_64-unknown-linux-gnu checking host system type. x86_64-unknown-linux-gnu checking for gcc. gcc checking for C compiler default output file name. a.out checking whether the C compiler works. yes checking whether we are cross compiling. no checking for suffix of executables. checking for suffix of object files. o checking whether we are using the GNU C compiler. yes
This took a while to get right. I had this issue when cross-compiling in Ubuntu for an ARM target. I solved it with:
PATH=$PATH:/ccpath/bin CC=ccname-gcc AR=ccname-ar LD=ccname-ld CPPFLAGS="-nostdinc -I/ccrootfs/usr/include . " LDFLAGS=-L/ccrootfs/usr/lib ./autogen.sh --build=`config.guess` --host=armv5tejl-unknown-linux-gnueabihf
Notice CFLAGS is not used with autogen.sh/configure, using it gave me the error: «configure: error: C compiler cannot create executables». In the build environment I was using an autogen.sh script was provided, if you don’t have an autogen.sh script substitute ./autogen.sh with ./configure in the command above. I ran config.guess on the target system to get the —host parameter.
After successfully running autogen.sh/configure, compile with:
PATH=$PATH:/ccpath/bin CC=ccname-gcc AR=ccname-ar LD=ccname-ld CPPFLAGS="-nostdinc -I/ccrootfs/usr/include . " LDFLAGS=-L/ccrootfs/usr/lib CFLAGS="-march=. -mcpu=. etc." make
The CFLAGS I chose to use were: «-march=armv5te -fno-tree-vectorize -mthumb-interwork -mcpu=arm926ej-s». It will take a while to get all of the include directories set up correctly: you might want some includes pointing to your cross-compiler and some pointing to your root file system includes, and there will likely be some conflicts.
I’m sure this is not the perfect answer. And I am still seeing some include directories pointing to / and not /ccrootfs in the Makefiles. Would love to know how to correct this. Hope this helps someone.
How do you specify the location of libraries to a binary? (linux)
For this question I’ll be using a specific example, but really this generalizes to pretty much any binary on linux that can’t seem to find its’ dependent libraries. So, I have a program that won’t run because of missing libraries:
./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory
linux-vdso.so.1 => (0x00007fff18b01000) libcorona-1.0.2.so => not found libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000) libm.so.6 => /lib/libm.so.6 (0x00007f09755af000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000) libc.so.6 => /lib/libc.so.6 (0x00007f0975040000) libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000) /lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)
oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null /usr/local/lib64/libcorona-1.0.2.so /home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so
3 Answers 3
For a once-off, set the variable LD_LIBRARY_PATH to a colon-separated list of directories to search. This is analogous to PATH for executables, except that the standard system directories are additionally searched after the ones specified through the environment.
LD_LIBRARY_PATH=/usr/local/lib64 ./cart5
If you have a program that keeps libraries in a non-standard location and isn’t able to find them on its own, you can write a wrapper script:
#!/bin/sh if [ -n "$LD_LIBRARY_PATH" ]; then LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64 else LD_LIBRARY_PATH=/usr/local/lib64 fi export LD_LIBRARY_PATH exec /path/to/cart5 "$@"
The list of standard system directories is kept in /etc/ld.so.conf . Recent systems allow this file to include other files; if yours contains something like include /etc/ld.so.conf.d/*.conf , create a new file called /etc/ld.so.conf.d/mala.conf containing the directories you want to add. After you change /etc/ld.so.conf or an included file, run /sbin/ldconfig for your changes to take effect (this updates a cache).
( LD_LIBRARY_PATH also applies to many other unices, including FreeBSD, NetBSD, OpenBSD, Solaris and Tru64. HP-UX has SHLIB_PATH and Mac OS X has DYLD_LIBRARY_PATH . /etc/ld.so.conf has analogs on most unices but the location and syntax differs more widely.)
Where do I put third-party libraries to set up a C++ Linux development environment?
I’m not new in C++ although I’m new in Linux. I’m using CMake to precompile a cross-platform game engine with some third-party components, but I have a lot of doubts about using libraries. My question is how to work with third-party libraries and where to put them. Apt installs libs in their official place (/usr/local, /usr/lib/ ..) but I develop in Windows using local libs that are in a folder in my project dir. Also, I need a good tutorial to know the rules of how libraries work. For example: when trying to compile my project, luabind is asking for liblua.s0.1, but AFAIK there is no way to generate this library with the source provided by Lua (at least doing make, make install). I know, this question is fuzzy but I haven’t enough experience to be more concise. Update: After reading some answers, a more concise question is the following. If I install all third-party libraries, how can I distribute my program? How do I manage dependencies without using a large readme?
4 Answers 4
Where to put libraries
The best solution is to use your Linux distribution’s packaging system ( apt-get , yum , or similar) to install libraries from distro-provided packages wherever possible.
If the distro’s packaged libraries aren’t of a recent enough version, or if you need some nonstandard build options, or if you need a library that your distro doesn’t provide, then you can build and install it yourself. You have two main options for where to put the library:
- /usr/local (libraries under /usr/local/lib , headers under /usr/local/include ). This installs the libraries systemwide and is probably the simplest solution, since you should then be able to build against them without taking any extra steps. Do NOT install libraries directly under /usr , since that will interfere with your distro’s packaging system.
- Under your project directory, as you did under Windows. This has the advantages of not requiring root access and not making systemwide changes, but you’ll have to update your project’s include paths and library paths, and you’ll have to put any shared library files someplace where the dynamic linker can find them (using LD_LIBRARY_PATH or ld.so.conf — see the link for more details).
How libraries work
See David A. Wheeler’s excellent Programming Library HOWTO. I’d recommend reading that then posting any specific questions as new topics.
How to distribute your program
Traditionally, Unix / Linux programs do not include copies of their dependencies. It’s instead up to the end user or developer to install those dependencies themselves. This can require a «large README,» as you said, but it has a few advantages:
- Development libraries can be installed, managed, and updated via the distro’s package manager, instead of each source copy having its own set of libraries to track.
- There’s only one copy of any given library on a system, so there’s only one place that needs updating if, for example, a security flaw is found. (For example, consider the chaos that resulted when zlib, a very widely used compression library, was found to have a security flaw, so every application that included an affected version needed to be updated.)
- If your program is popular enough (and is open source or at least freely available), then package maintainers for various Linux distributions may want to package it and include it in their distro. Package maintainers really don’t like bundled libraries. See, for example, Fedora’s page on the topic.
If you’re distributing your program to end users, you may want to consider offering a package ( .dpkg or .rpm ) that they could simply download and install without having to use source. Ideally, from the end user’s perspective, the package would be added to distros’ repositories (if it’s open source or at least freely available) so that users can download it using their package managers ( apt-get or yum ). This can all get complicated, because of the large number of Linux distros out there, but a Debian/Ubuntu compatible .dpkg and a Red Hat/CentOS/Fedora-compatible .rpm should cover a good percentage of end users. Building packages isn’t too hard, and there are good howtos online.