Prepending custom dirs ($ZPFX/{include,libs}) to CPP..../LDFLAGS with use of config.site file of autotools? - configure

I'm using a $CONFIG_SITE set to $ZPFX/share/config.site file containing:
CPPFLAGS="-I$ZPFX/include $CPPFLAGS"
LDFLAGS="-L$ZPFX/lib $LDFLAGS"
where $ZPFX variable is my custom user prefix, similar to ~/.local.
Now, the problem is that the system iconv.h (under path /usr/include) isn't found because of this, as only the above pre-set (with use of config.site) -I$ZPFX…/-L$ZPFX… are being passed to the test program, as the following lines from config.log are showing:
configure:21831: gcc -o conftest -g -O2 \
-I/home/q/.local/share/zinit/polaris/include \
-L/home/q/.local/share/zinit/polaris/lib \
conftest.c -lxml2 -liconv >&5
/usr/bin/ld: cannot find -liconv
collect2: error: ld returned 1 exit status
($ZPFX is expanded to its value, which is: /home/q/.local/share/zinit/polaris)
The Question: how to append (prepend) any custom ($ZPFX/… in my case) directories to CPPFLAGS/LDFLAGS, preserving their default values? So that my custom libraries are only given higher precedence, and not exclusivity?
What I've tried
As it can be seen, I've tried to prepend to the flags by appending any occurred values at the time of sourcing the config.site file, by "…$CPP…/$LDFLAGS" :
CPPFLAGS="-I$ZPFX/include $CPPFLAGS"
LDFLAGS="-L$ZPFX/lib $LDFLAGS"
However this has no effect.
I'm also waving between not-appending and appending any typically used system-libraries paths: /usr/include and /usr/lib{,64}, however I don't like the idea, because some system might use e.g.: /opt/… for main prefix, making such hack not working at all.

The documentation explains how configure scripts use CONFIG_SITE. The parts most relevant to your question are near the beginning:
If the environment variable CONFIG_SITE is set, configure uses its
value as a space-separated list of shell scripts to read [...].
Otherwise, it reads the shell script prefix/share/config.site if it
exists, then prefix/etc/config.site if it exists. [...]
Site files can be arbitrary shell scripts
You ask:
how to append (prepend) any custom ($ZPFX/… in my case) directories
to CPPFLAGS/LDFLAGS, preserving their default values? So that my
custom libraries are only given higher precedence, and not
exclusivity?
You need to read only a little between the lines to recognize that the mechanism by which configure scripts read site defaults must be via the . command. That the files may contain arbitrary shell code and that they can set shell variables within configure implies that they are going to be parsed and executed as shell code.
The docs also say what configure does by default when you do not provide CONFIG_SITE, so your site config can do that, too, if you wish. And that's what I would do, to start. Specifically, add this at the beginning of $ZPFX/share/config.site:
test -r "${prefix}/share/config.site" && . "${prefix}/share/config.site"
test -r "${prefix}/etc/config.site" && . "${prefix}/etc/config.site"
Now you have the same settings that configure would get when you don't define CONFIG_SITE at all. What remains is to insert your own additional settings, and the code already presented in the question ought to be fine for that:
CPPFLAGS="-I$ZPFX/include $CPPFLAGS"
LDFLAGS="-L$ZPFX/lib $LDFLAGS"
Additionally, you write:
I'm also waving between not-appending and appending any typically used
system-libraries paths: /usr/include and /usr/lib{,64}, however I
don't like the idea, because some system might use e.g.: /opt/… for
main prefix, making such hack not working at all.
I don't like that idea either.
In the first place, /usr/include, /usr/lib, etc. are not just commonly used, they are typical toolchain defaults. You pretty much never need to explicitly specify toolchain defaults, and trying to do so is more likely to cause harm than good. For example, it could cause breakage in cases such as you posit, where the defaults for the toolchain actually being used are different from the usual ones.
But in the second place, your remarks convey an incorrect perspective on what you're doing with site defaults. These are site-specific, which may mean machine specific or may mean more broadly specific to a group or organization, but any way around, you can set only your own site defaults, not those of other sites.
And that leads me to one final point: the site configuration is part of your site, not part of your project. Hopefully this is not a point of confusion for you, but I want to be sure it is clear. You should not be planning to distribute your site configuration file outside your own site, nor to rely on people wanting to build your project at other sites specifically to use a site configuration file to inject build settings.

Related

clang include multiple search path in the same directory

According to Clang doc:
-I < directory >
Add the specified directory to the search path for include files.
I wounder if there a way to add multiple search path on the same directory with one -I command, something like this:
-I"Dir1/SubDir/SubDir/SubDir/{IncludePath1,IncludePath2,IncludePath3}"
My project folder tree (unfortunately) is in a formation that there are 2 main folders for include paths which each one includes many paths for the -I option. This cause the clang command to be very long and i will give an example:
clang (...)
-I"Dir1/SubDir/SubDir/.../SubDir/IncludePath1"
-I"Dir1/SubDir/SubDir/.../SubDir/IncludePath2"
-I"Dir1/SubDir/SubDir/.../SubDir/IncludePath3"
-I"Dir1/SubDir/SubDir/.../SubDir/(And so on...)"
-I"Dir2/SubDir/SubDir/.../SubDir/IncludePath1"
-I"Dir2/SubDir/SubDir/.../SubDir/IncludePath2"
-I"Dir2/SubDir/SubDir/.../SubDir/IncludePath3"
-I"Dir2/SubDir/SubDir/.../SubDir/(And so on...)"
So again i wonder if there a way to tell clang to search with one command multiple search path or maybe make it search within a specific dir
Use options -isysroot and -iwithsysroot:
clang -isysroot"Dir1/SubDir/SubDir/SubDir/" -iwithsysroot"/IncludePath1/" \
-iwithsysroot"/IncludePath2/" -iwithsysroot"/IncludePath3/"
Unfortunately, this solution only works for one main folder and it also makes those include folders system ones, i.e., Clang won't show any warnings for them.
Also, -iwithsysroot is pretty long, so you may not save much typing there :)
But I'm not aware of any better way to do this directly via Clang options.
Although you could always write a shell script to ease the job...
Note. While digging through Clang command line reference trying to find a better solution, I came across option -ivfsoverlay that seems like it maybe could solve your problem.
I wasn't able to make it work, though, but I still decided to leave it here, maybe it'll be useful for you.

canonical way to use pkg-config variables in Makefile.am

A bunch of projects foo-A-B, foo-B-C, foo-A-C etc. each depend on foo-A, foo-B, foo-C etc.
Each of foo-X installs a pkg-config file (foo-X.pc.in) which contains a variable srcdir=#datarootdir#/foo/foo-B. A foo-X-Y project needs to refer to files in Xsrcdir and Ysrcdir.
Currently we do it like this in configure.ac:
PKG_CHECK_MODULES([foo_X], [foo-X])
AC_ARG_VAR(XSRC, "Source directory for foo-X")
AS_IF([test -z "$XSRC"], [XSRC=`pkg-config --variable=srcdir foo-X`])
(so Makefile.am gets to have rules like compile "$XSRC"/file.bar $#). This also lets developers override XSRC on running ./configure.
My question: is there a more canonical way to use non-standard pkg-config variables in autotools configury/makefiles? For e.g. libdir, I see pkg-config sets the variables itself so no configure.ac line is needed apart from PKG_CHECK_MODULES; are there other m4 macros we should be using?
I know this is fairly late, but since somebody was asking me about this recently, I thought it might be worth answering this too.
What you're looking for is PKG_CHECK_VAR, indeed most of that code can be replaced by a single line:
PKG_CHECK_VAR([XSRC], [foo-X], [srcdir], ,
AC_MSG_FAILURE([Unable to find value for XSRC]))
The error message is a bit less clear than the one triggered by PKG_CHECK_MODULES, but it also triggers in case the srcdir variable is not defined.
I wrote some more details as part of my Autotools Mythbuster.

How to make gcc uses march=native as default?

Is there a way to change the specs file so that it will pass -march=native if nothing is specified in command line?
Related things in the default specs file is:
*cc1:
%(cc1_cpu)
*cc1_cpu:
%{march=native:%>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
I am not sure how specs works. Simply specifying -march=native before or after %(cc1_cpu) doesn't work. However, this line does take effect because GCC will report error if I put -something_wierd instead of -march=native.
Another thing I noticed is if I put %{march=i386:-something_wierd} before %(cc1_cpu), gcc reports error so looks like -march=i386 is always passed in if nothing is specified, so is there a way to distinguish between nothing specified and -march=i386 in specs file?
BTW, what does %> do? Seems like it is not specified in the documentation.
I am using MinGW's gcc-4.6.2.
Referring to your last question: The gcc 4.6.1 sources (gcc/gcc.c) contain the following comment on %>:
%>S Similar to "%<S", but keep it in the GCC command line.
For the sake of completeness following the comment for %< form the same file:
%<S remove all occurrences of -S from the command line.
Note - this command is position dependent. % commands in the
spec string before this one will see -S, % commands in the
spec string after this one will not.
To answer the first question in short: yes, but ....
... the only generic solution I found has the significant drawback that the -march option will be ignored, so every build is done as if -march=native had been specified. Anyhow there is a workaround to that.
1 The solution (without workaround)
Create a specs-file called let's say specs.nativealways containing:
*cc1_cpu:
%<march=* -march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
When using the specs-file (for example by invoking gcc with the option -specs=specs.nativealways) the build will be done as if -march=native was specified (with the mentioned drawback that any occurrence of option -march=<arch> would have simply been ignored).
2 The workaround
To still by able to override the newly configured default behavior one can use a modified version of the specs-file described above, introducing a new option called -myarch using the same syntax as -march (except for -myarch=native, which won't work, which does not metter as native now is the default).
The modfied specs-file looks like this:
*cc1_cpu:
%<march=* %{myarch=*:%<myarch* -march=%* ; :-march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
PS: This has been tested with with gcc 4.6.2 on Linux, but should work on MinGW.
While not a direct answer to your question, you can reach a very similar effect by defining CFLAGS and CXXFLAGS in your shell's initialization file. 99% of the Makefiles are sufficiently standard to pick up the environment values and pass the flags to gcc.
*cc1_cpu:
+ %{!march*:-march=native}

A simple (trivial) c++ makefile on UNIX

I am trying to make a makefile for one cpp file. I've tried googling and none of the examples I've seen have helped... I keep getting errors when I type make. Here is what I have...
Interpreter: Interpreter.o
g++ -o Interpreter Interpreter.o
Interpreter.o: Interpreter.cpp
g++ -c Interpreter.cpp
When I type make I get this error... "'ake: Fatal error: Don't know how to make target `Interpreter.o"
Where am I going wrong?
OK. A few simple things to start with here:
As mentioned in some of the comments, the makefile file must be named properly for make to find it. You can try specifing it manually with the -f flag to verify that it is being found.
Make is one of those few unfortunate languages where whitespace is important. The rules must not have a tab in front of them, and the commands for the rules should all have exactly one tab in front of them. When I checked your code above in the SO editor, it looked like your commands had two tabs at the front instead of one.
If I'm reading those rules right, you need a file named Interpreter.cpp in your working directory for this to work. If you don't have that file, you'll get an error.
If all else fails, try running make with the debugging flag (-d). This should give you more information about the decisions it is making.

With autoconf/automake, how do I specify include file paths?

Let's say I want to have the generate makefile pass some specific header paths to g++.
What do I need to add to configure.ac or Makefile.am to specify this?
(note - I do not want to pass it in the CPPFLAGS with ./configure. I want those paths baked in before that step)
EDIT:
Specifically, I want to to include let's say /usr/include/freetype and /mypath/include.
I put AC_CHECK_HEADERS([freetype/config/ftheader.h]) and it passes, but doesn't seem to add it to the -I passed to g++.
I also did try adding CPPFLAGS=-I.:/usr/include/freetype:/mypath/include, but it screws up and puts -I twice, the first as -I. and it ignores the 2nd -I.
Since the question was about what to put in an automakefile, I would have thought AM_CPPFLAGS was the right variable to use to add includes and defines for all C/C++ compiles. See http://www.gnu.org/software/automake/manual/html_node/Program-Variables.html
Example:
AM_CPPFLAGS = -I/usr/local/custom/include/path
Hard coding paths into the package files is absolutely the wrong thing to do. If you choose to do that, then you need to be aware that you are violating the basic rules of building a package with the autotools. If you specify /mypath/include in your package files, you are specifying things specific to your machine in a package that is intended to work on all machines; clearly that is wrong. It looks like what you want is for your package (when built on your machine) to look for header files in /mypath. That is easy to accomplish without bastardizing your package. There are (at least) 3 ways to do it:
Use a config.site file. In /usr/local/share/config.site (create this file if necessary), add the line:
CPPFLAGS="$CPPFLAGS -I/mypath/include"
Now any package using an autoconf generated configure script with the default prefix (/usr/local) will append -I/mypath/include to CPPFLAGS and the headers in /mypath/include will be found.
If you want the assignment to be made for all builds (not just those to be installed in /usr/local), you can use this:
Put the same line specifying CPPFLAGS in $HOME/config.site, and set CONFIG_SITE=$HOME/config.site in the environment of your default shell. Now, whenever you run an autoconf generated configure script, the assignments from $HOME/config.site will be made.
Simply specify CPPFLAGS in the environment of your default shell.
All of these solutions have two primary advantages over modifying your build files. First, they will work for all autoconf generated packages (as long as they follow the rules and don't do things like assigning user variables such as CPPFLAGS in the build files). Second, they do not put your machine specific information into a package that ought to work on all machines.

Resources