Environment variables that one should update when using a new compiler - gcc

Say a system admin provides a new version of the gcc compiler available on /some/path on a machine where I build software (all types of software including open source, 3rd party tools, my own programs, etc.):
I usually update the following three environment variables $PATH, $LD_LIBRARY_PATH and $MANPATH, according to what I understand is standard practice for interfacing with general building tools (e.g. autoconf, cmake, etc.) or scripts.
setenv MY_GCC /some/path
setenv PATH $MY_GCC/bin:$PATH
setenv LD_LIBRARY_PATH $MY_GCC/lib64:$LD_LIBRARY_PATH
setenv MANPATH $MY_GCC/share/man:$MANPATH
Here I have a quick question: is there really a reason to update LD_LIBRARY_PATH (why would programs link against a compiler?).
But more generally, what environment variables should one update upon the installation of a new compiler to guarantee a proper building environment?

It depends.
Generally, you do not need to set up any environment variables other than PATH to have a proper building environment (and if you use an IDE, not even that may be necessary, though you might have to tell the IDE where to find the compiler if it lives in an unexpected, non-standard location).
If you use something like autoconf (or CMAKE, or any similar thing), and especially if you have several compiler versions (or cross compilers) on the system, you may want to set variables like CC or CXX to a reasonable default just to be sure (and modify them accordingly if you want something else).
Though if your compiler has its target appended to its name (as in most builds), this is probably not necessary. At least, it works perfectly well for me without doing anything special.
If English is not your native language and your GCC was built with locale support (most stupid idea ever, if you ask me), you may want to set LC_ALL to "C". Otherwise you'll notice that your "unreadable" error messages won't get you much help if you ask for a compiler problem on a forum.
If you have a ramdisk (or SSD) in addition to a normal harddisk, but your projects are on the normal harddisk, you may want to set TMPDIR (even if you always compile with -pipe, since this sometimes seems to create temp files anyway for a reason I don't understand).
If you have non-standard locations for libraries that you want to use, you can set LIBRARY_PATH, but I advise against it. It is better to have your build scripts (or project settings in the IDE) such that these locations are given to the linker on the commandline (or passed through configure with something like --with-foo-path=...). This guarantees that your projects build everywhere and anywhere without requiring someone else to performa a magic dance with some unknown, obscure environment variables. The same goes for C_INCLUDE_PATH.

Related

How to set "BR2_PACKAGE_HOST_ENVIRONMENT_SETUP" in buildroot

I want to various projects for various platforms, and as such I've concluded that the easiest way to to this is probably going to just have buildroot create the toolchain and then alter the environment to use said toolchain.
From section 8.14.1 of the buildroot manual:
For your convenience, by selecting the option
BR2_PACKAGE_HOST_ENVIRONMENT_SETUP, you can get setup-environment
script installed in output/host/and therefore in your SDK. This script
can be sourced with . your/sdk/path/environment-setup to export a
number of environment variables that will help cross-compile your
projects using the Buildroot SDK: the PATH will contain the SDK
binaries, standard autotools variables will be defined with the
appropriate values, and CONFIGURE_FLAGS will contain basic ./configure
options to cross-compile autotools projects. It also provides some
useful commands. Note however that once this script is sourced, the
environment is setup only for cross-compilation, and no longer for
native compilation.
Alright, that sounds pretty much like exactly what I want. However, I have not figured out how to set BR2_PACKAGE_HOST_ENVIRONMENT_SETUP. I found no mention of anything similar when looking through make menuconfig, I tried to grep the entire buildroot source tree for that string with no luck, and simply exporting it as an environment variabl did not produce a different result either. So, how do I set BR2_PACKAGE_HOST_ENVIRONMENT_SETUP, exactly?
I just stumbled across the same problem. The option was submitted in April 2020, so buildroot-2020.02.8 (the long term support version as of writing) doesn't support it, whereas the PDF available online is newer -- I suspect you are using the same version; the buildroot download page presents the longer term support version first.
In menu-config, you do a search ("/") of HOST_ENVIRONMENT and then you find your answer:
screenshot

setting up autotools to link single system library statically

I have a project, where I want to link one of system libraries statically. The project uses GNU build system.
In configure.ac I have:
AC_CHECK_LIB(foobar, foobar_init)
On development machine this library is installed in /usr/lib/x86_64-linux-gnu. It is detected, but it is linked dynamically, which causes issues, as it is not present on some machines. Linking it statically (-Wl,-Bstatic etc.) works fine, but I don't know how to set this up in autotools. I tried forcing this into Makefile.am link flags for the project, but it still gives a preference to dynamic library.
I also tried using --enable-static with ./configure, but it seems to have no effect on system libraries.
If you want to link the whole program statically, then you should pass the --disable-shared option to configure. You might or might not need also to pass --enable-static, depending on the default value for that option (which you can influence via your configure.ac file). You really should consider doing this.
You should also consider making this the installer's problem, not the build system's. Let it be the installer's responsibility to ensure that all the shared libraries needed by the program are provided by the systems where it is installed. This is very common; in fact, it is one of the inspirations for package-management systems such as yum / dnf and apt, and their underlying packaging formats.
If you insist on linking only one library statically, while linking everything else dynamically, then you'll need to jump through a few more hoops. The objective will be to emit link options that cause just that library to be linked statically, without changing other libraries' linking. With the GNU toolchain, and supposing that the program is otherwise being linked dynamically, that would be this combination of options:
-Wl,-Bstatic -lfoobar -Wl,-Bdynamic
Now consider the documentation of the AC_CHECK_LIB() macro:
Macro: AC_CHECK_LIB (library, function, [action-if-found],
[action-if-not-found], [other-libraries])
[...] action-if-found is a list of shell commands to run if the link with the library succeeds; action-if-not-found is a list of shell
commands to run if the link fails. If action-if-found is not
specified, the default action prepends -llibrary to LIBS and defines
'HAVE_LIBlibrary' (in all capitals). [...]
Note in particular the default behavior in the event that the optional arguments are not provided (your present case) -- that's not quite what you want, at least not by itself. I suggest providing at least an alternative behavior for action-if-found case, and you could consider also making configure fail in the action-if-not-found case. The latter is left as an exercise; implementing just the former might look like this:
AC_CHECK_LIB([foobar], [foobar_init], [
LIBS="-Wl,-Bstatic -lfoobar -Wl,-Bdynamic $LIBS"
AC_DEFINE([HAVE_LIBFOOBAR], [1], [Define to 1 if you have libfoobar.])
])
You should also pay attention to the order of your AC_CHECK_LIB() invocations. As its docs go on to say:
This macro is intended to support building LIBS in a right-to-left
(least-dependent to most-dependent) fashion such that library
dependencies are satisfied as a natural side effect of consecutive
tests. Linkers are sensitive to library ordering so the order in which
LIBS is generated is important to reliable detection of libraries.
If you find that you still aren't getting what you want, then have a look at the link commands that make actually executes. You need to understand what's wrong about them before you can determine how to fix the problem.
With all that said, I observe that the above treatment is basically a hack, and it makes your build system much less resilient. It introduces dependencies on GNU toolchain options (which some other toolchains may nevertheless accept), and it assumes dynamic linking is being performed overall. It may be possible to resolve those issues with additional Autoconf code, but I urge you to instead go with one of the first two alternatives I described.

What is happening when you set a compilation path?

I understand it is somehow making a connection so that a compiler when envokes connects a source code to whatever libraries that it needs to.
But what is going on a more technical level, or better put what do I need to know in order to confidentally compile code.
I'm working with C++ and MinGW, and have started to look into build files and stuff for Sublime Text 2 (Have learned mostly under unix, or Java + eclipse so far). But what I don't understand what is adding a compiler to your path do for you?
Do I need to add it for every folder I want to compile from? Or is it system wide? I'm really learning this stuff for the first time, we we're never showed how to set up development environments or even deploy code on other systems.
You probably mean include paths and library paths in the compiler:
include paths: where the compiler will look for headers; and
library paths: where the linker, invoked by the compiler, will look for binary libraries to finish building your project.
If that is the case, look here for a gentle explanation.
Basically, what is happening is that the compiler looks in certain places for symbols defined by the operating system and other libraries installed system-wide.
In addition to those paths, you need to tell the compiler where to find the symbols defined in your own project.
You may also mean something related to installing the compiler itself or configuring the editor to use it.
In that case, what is happening is that you need to tell the build system where to find the executable for the compiler.
Basically, what is probably happening is that your editor wants to know where the compiler is so that it can provide real time feedback on your code. Adding the compiler to the system path will usually, but not always, solve your problem.
In more detail:
A C++ build is a rather complex tool chain, involving determining dependencies, preprocessing, compiling, and linking. There are tools that automate that tool chain, and those tools are in turn wrapped into the functionality of modern IDEs like Eclipse, Visual C++, or Sublime Text 2. You many need to tell your editor where to find the tools it uses to provide you with those services.

Setting CMake module search path

I've written a CMake module to find libclang:
find_path(LibClang_INCLUDE_DIR clang-c/Index.h)
find_library(LibClang_LIBRARY NAMES clang)
But I've installed libclang via MacPorts to /opt/local/libexec/llvm-3.0/lib and /opt/local/libexec/llvm-3.0/include. Since this isn't a normal system location, CMake doesn't find it.
What's the best way to show CMake where it is? How can I find out where CMake is searching? I don't think moving the library to a more normal location is an option because I don't want to move things away from where MacPorts put them, and I also have Apple's official clang binaries (not including libclang) on my system.
Add the HINTS or PATHS flag to suggest locations for it to search.
If you want to make a general way to include non-standard locations, you can do two things. One is make sure the users know to put the non-standard location on the LD_LIBRARY_PATH environment variable and then suggest that as a HINT to find_path and find_library with ENV LD_LIBRARY_PATH.
The other option is to put a custom environment variable and tell users to set that if it's non-standard. For instance, CLANG_ROOT, and include that in the HINTS.
Of course, you can do both and it would be the most general.

How to specify preference for compilers when using enable_language [cmake]

When using enable_language in cmake, it always search for compilers in a certain default sequence. I wonder how I can change this sequence. For example, if my system has both ifort (icc) and gfortran (g++) installed, and I want to use ifort (icc) instead of the gfortran (g++), how could I set up this?
CLARIFICATION: I know we can switch the compiler explicitly by changing the variable CMAKE_Fortran_Compiler, but what I want to do is rather to modify the default sequence that cmake searches for available compilers if the user does not specify such a preference.
From what I currently found, a work-around is to set CMAKE_Fortran_Compiler before project(xxx), so that this variable can never gets overridden later, but clearly this is not the best way, since I will need gfortran if there turns out to be no ifort available.
By the way, what's the best place to look for this kind of information? The documentation does not seem to be very complete..
Thanks!
The right place to look is the CMake FAQ, which answers your question.
Omegaice's answer will work, as will CC=/path/to/icc cmake ..., see also this discussion thread.
Setting CMAKE_Fortran_Compiler before the project call is strongly discouraged (as the FAQ will tell you).
Note that manually calling enable_language is no different from specifying the languages with the project call (or indeed not specifying them, in which case they default to C and CXX), since that calls enable_language internally.
You can probably specify which compiler to use by doing ccmake .. -DCMAKE_Fortran_Compiler=<executable> (where <executable> is either the name of the compiler or the full path to the compiler) instead of setting it in the CMakeLists.txt.

Resources