Remove a compiler / linker flag from autotools configure - makefile

There is a project (Antlr3 for C) that can be built with ./configure && make && make install.
One of the flags that are used in the compilation command is -Wl,-soname -Wl,libantlr3c.so. The whole command is:
libtool: link: gcc -shared .libs/antlr3baserecognizer.o .libs/antlr3basetree.o \
.libs/antlr3basetreeadaptor.o .libs/antlr3bitset.o .libs/antlr3collections.o \
.libs/antlr3commontoken.o .libs/antlr3commontree.o .libs/antlr3commontreeadaptor.o \
.libs/antlr3commontreenodestream.o .libs/antlr3convertutf.o .libs/antlr3cyclicdfa.o \
.libs/antlr3debughandlers.o .libs/antlr3encodings.o .libs/antlr3exception.o \
.libs/antlr3filestream.o .libs/antlr3inputstream.o .libs/antlr3intstream.o \
.libs/antlr3lexer.o .libs/antlr3parser.o .libs/antlr3rewritestreams.o \
.libs/antlr3string.o .libs/antlr3tokenstream.o .libs/antlr3treeparser.o \
-m64 -Wl,-soname -Wl,libantlr3c.so -o .libs/libantlr3c.so
How can I remove only the -Wl,-soname -Wl,libantlr3c.so part?
I understand that the compiler and linker flags can be overridden with CFLAGS and LDFLAGS in the configure command. According to this link, it's something like
./configure CFLAGS=blah LDFLAGS=blah
Although I understand that they can/should be used as environment variables, something like
CFLAGS=BLAH LDFLAGS=blah ./configure
However, I think that those uses would try to override all the CFLAGS or LDFLAGS. I only want to exclude the -soname flag (which, I understand, -Wl, means that the compiler passes a flag to the linker.
None of my attempts with things like LDFLAGS=-soname= or CFLAGS="-Wl,soname -Wl,", and variations of them, were successful so far.
From this question it looks as if it was possible to remove flags from within a Makefile, but I can't see that being applicable to overriding flags from the command line with the configure command. It's also possible to provide these variables to the make command instead of the configure command, but that wasn't successful either.
Note, it wouldn't make sense for me to change the Makefile, since it's generated out of the configure command.

You cannot remove -soname because it's part of the way you build a shared library with GCC, and comes straight from libtool. Since you can't really build a shared object for ELF without a soname (well, you can, but it's not really useful) libtool won't let you remove that.
You probably are better off declaring what you try to achieve, because I have a feeling it has nothing really to do with -soname in that case.

Related

Cannot pass flags to Makefile to compile my code

I have a project that basically compiles from the command line in the following form:
g++ -o stack_raster stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
I made a Makefile, and this is the content:
CXX =g++
LDDFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
However I got a collect2: error: ld returned 1 exit status.
A second variation of my Makefile I tried was:
CXX = g++
CPPFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rem -f stack_raster
but I still receive the following message (even though the compile flags appear as they should for my program to compile successfully).
collect2: error: ld returned 1 exit status
<builtin>: recipe for target `stack_raster` failed
make: *** [stack_raster] Error 1
Does anyone could help me with a reference or hint about my problem, and how could I tackle it?
Does anyone could help me with a reference or hint about my problem, and how could I tackle it?
To begin with, you should have a look at the actual link command that make executed. It should have been echoed to make's output just before the error message from collect2. Understanding what's wrong with the command is the first step in determining how to fix your makefile.
In the first case, the command is probably something like
g++ stack_raster.cpp -o stack_raster
In the second, it is probably something like
g++ -lgdal -lboost_system -lboost_filesystem stack_raster.cpp -o stack_raster
The latter is probably also very similar to what you would get with the first makefile if you corrected the spelling of LDDFLAGS to LDFLAGS.
You will note that the library flags come in a different place in that command than they do in your manual command, and I assume you know that the order of objects and library flags on the linker command line is significant to Unix-style linkers such as GNU's (which is the one that the g++ driver will use).
You can certainly fix this by writing an explicit rule, as you describe in your own answer, but your makes' built-in rules may be up to the task, too. If you are using GNU make then they certainly are. For this purpose it is useful to know what the built-in rules actually are, and essential to know what the variables on which these rules depend mean.
Specifically,
LDFLAGS provides options to pass when invoking the linker, and conventionally, they appear on the command line before the objects being linked. As a result, this variable typically is not appropriate for specifying libraries (but it is fine for other link-specific options, such as -L to add directories to the library search path).
CPPFLAGS provides options for modulating the behavior of the C preprocessor (including when compiling C++). These do not typically appear at all in link(-only) commands executed by make, but they will appear (early) in commands for compiling object files from C or C++ sources, and in rules for building executables directly from C or C++ sources.
Neither of those is what you want, but if you are using GNU make, then its documentation for the former explicitly tells you what (with that make implementation) you should do instead:
Extra flags to give to compilers when they are supposed to invoke the
linker, ‘ld’, such as -L. Libraries (-lfoo) should be added to the
LDLIBS variable instead.
(emphasis added)
In GNU make, and perhaps some others, the LDLIBS variable serves exactly the purpose you need: to specify the libraries to link. These will appear at the end of the link command line from built-in rules, as you can confirm from GNU make's catalog of implicit rules, or from the list obtainable by running make -p in a directory containing no makefile.
So, with GNU make you can get the build you seem to want from the built-in rules, with this:
CXX = g++
LDLIBS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
In closing, I note that cleaning before building by default, as your examples do and mine imitates, largely defeats the purpose of using make instead of a simple script. Part of the point of make is to do the minimum work necessary, and if your target executable is present and not out of date with respect to its sources then there is no reason to force it to be rebuilt.
Check out the answer:
Set up my makefile to compile C with just "make"
YOu have to specify in the Makefile the file you want to create in this case stack_raster.exe and the objective file in this case stack_raster.cpp and specify the command line arguments you normally pass for compiling. So the Makefile would be something like:
CXX=g++
stack_raster.exe: stack_raster.cpp
g++ -o stack_raster.exe stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
all: clean stack_raster.exe
clean:
rm -f stack_raster.exe

When i should use ld instead of gcc?

I want to know when i should use ld linker instead off gcc. I just wrote a simply hello world in c++, of course i include iostream library. If i want make a binary file with gcc i just use:
g++ hello hello.cpp
and i've got my binary file.
Later i try to use ld linker. To get object file i use:
g++ -c hello.cpp. Ok that was easy, but the link command was horrible long:
ld -o hello.out hello.o \
-L /usr/lib/gcc/x86_64-linux-gnu/4.8.4/ \
/usr/lib/gcc/x86_64-linux-gnu/4.8.4/crtbegin.o \
/usr/lib/gcc/x86_64-linux-gnu/4.8.4/crtend.o \
/usr/lib/x86_64-linux-gnu/crti.o \
/usr/lib/x86_64-linux-gnu/crtn.o \
/usr/lib/x86_64-linux-gnu/crt1.o \
-dynamic-linker /lib64/ld-linux-x86-64.so.2 -lstdc++ -lc
I know fact that gcc uses the ld.
Using gcc is better in all cases or just in most cases? Please, tell me somethink about cases where ld linker has advantage.
As you mentioned, gcc merely acts as a front-end to ld at link time; it passes all the linker directives (options, default/system libraries, etc..), and makes sure everything fits together nicely by taking care of all these toolchain-specific details for you.
I believe it's best to consider the GNU toolchain as a whole, tightly integrated environment (as anyone with an experience of building toolchains for some exotic embedded platforms with, say, dietlibc integration will probably agree).
Unless you have some very specific platform integration requirements, or have reasons not to use gcc, I can hardly think of any advantage of invoking ld directly for linking. Any extra linker-specific option you may require could easily be specified with the -Wl, prefix on the gcc command line (if not already available as a plain gcc option).
It is mostly a matter of taste: you would use ld directly when the command-lines are simpler than using gcc. That would be when you are just using the linker to manipulate a small number of shared objects, e.g., to create a shared library with few dependencies.
Because you can pass options to ld via the -Wl option, often people will recommend just using gcc to manage the command-line.

So what "is" AM_(F)CFLAGS?

The autotools documentation is very confusing. I am writng Fortran, so the AM_CFLAGS equivalent is AM_FCFLAGS. The two work exactly the same way (presumably).
First off, what actually "is" AM_CFLAGS, conceptually? Clearly, the "CFLAGS" bit is to do with setting compiler flags. But what does the "AM_" part mean?
There seems to be conflicting advice as to how to use it. Some say don't put it in Makefile.am, and some say don't put it in configure.ac. Who is right?
Here is my current Makefile.am:
AM_FCFLAGS = -Wall -O0 -C -fbacktrace
.f90.o:
$(FC) -c $(AM_FCFLAGS) $<
What I want to happen is to compile with "-Wall -O0 -C -fbacktrace" by default if I'm compiling with gfortran. However, a user might want to use a different compiler, eg FC=ifort, in which case they'll probably have to pass in FCFLAGS="whatever" and completely scrap AM_FCFLAGS
Can the user also override the default AM_FCFLAGS from the configure option if they're still using gfortran?
Basically, WTF?
AM_FCFLAGS (and similarly AM_CFLAGS and similar) are designed to not be user-overridable, so you should not put those options there unless you want them to always be present.
Users can pass their own FCFLAGS as part of their ./configure call — what you can do, if you want to default to those rather than what autoconf will default by itself, is to change configure.ac and compare the default flags (which to be honest I don't know for Fortran) to the current FCFLAGS, and if they match, replace FCFLAGS with your defaults.
In Makefile.am I had
AM_CFCFLAGS = -Wall -O0 -C -fbacktrace
Bad idea! It assumes that folks are using gfortran and/or won't want to override those defaults. So I deleted that line.
Instead, I now have the following lines in configure.ac:
AC_PROG_FC([gfortran], [Fortran 90]) # we need a Fortran 90 compiler
AS_IF([test x$FC = xgfortran -a x$ac_cv_env_FCFLAGS_set = x],
AC_SUBST([FCFLAGS], ["-Wall -O0 -C -fbacktrace"])
[Set some flags automatically if using gfortran])
AC_PROG_FC checks for gfortran that meets with Fortran 90 standards, and automatically sets FC and FCFLAGS.
The last 3 lines set sensible defaults if the user is using gfortran, but hasn't set FCFLAGS.
I discovered about ac_cv_env_FCFLAGS_set when I looked at config.log. It is set to "set" if the user sets their own FCFLAGS.
In Makefile.am I now have rules like:
.f90.o:
$(FC) -c $(FCFLAGS) $<
datetime_module.mod : datetime.o
datetime.o : datetime.f90 mod_clock.o mod_datetime.o mod_strftime.o mod_timedelta.o
mod_clock.o: mod_clock.f90 mod_datetime.o mod_timedelta.o
mod_datetime.o: mod_datetime.f90 mod_constants.o mod_strftime.o mod_timedelta.o
mod_timedelta.o: mod_timedelta.f90
It's starting to make sense now.

Using -flto with autotools

Given a C++ program that uses GNU autotools, what's the easiest way to compile it with -flto (link time optimization)? My understanding is that it is customary on Unix for such optimization flags to be specified by the user or packager, not by the programmer.
According to this post, the -flto flag needs to be passed as a compilation flag and as a linker flag, so:
./configure CXXFLAGS="-flto" LDFLAGS="-flto" ...
or possibly:
./configure CXXFLAGS="-flto" LDFLAGS="-Wc,-flto" ...
might work.

make command with math library

I need to just run the make command for makefile. But when I run this make command I get the error that "undefined reference to `log'" because I know this fact that it doesn't include math Library and we have to include at runtime. I know that if I run this using gcc comiler then i can write -lm at the end, it will include math library. My problem is I need to run it using make command that is- make lu.
In this if I write make lu -lm it is not linking math library. Please help
Using this link How to use LDFLAGS in makefile
I updated my make file but still same problem persists. Please Help.
SHELL=/bin/sh
BENCHMARK=ep
BENCHMARKU=EP
include ../config/make.def
OBJS = ep.o ${COMMON}/c_print_results.o ${COMMON}/c_${RAND}.o \
${COMMON}/c_timers.o ${COMMON}/c_wtime.o
include ../sys/make.common
LDLIBS=-lm
LDFLAGS=-lm
${PROGRAM}: config ${OBJS}
${CLINK} ${CLINKFLAGS} -o ${PROGRAM} $(LDFLAGS) $(LOADLIBES) ${OBJS} ${C_LIB}
ep.o: ep.c npbparams.h
${CCOMPILE} ep.c
clean:
- rm -f *.o *~
- rm -f npbparams.h core
Why does your makefile refer to all sorts of variables that don't exist, like LOADLIBES, C_LIB? Why do you set variables that you never use, like LDLIBS?
The reason it doesn't work is that you're putting the library reference in the LDFLAGS variable, which comes early in your link command before any of your object files. So when the linker goes to link in the math library it thinks that it's not needed because nothing is using it yet.
You have to put libraries at the end of the link line.
Since you already have the C_LIB variable at the end which you are not using, if you add:
C_LIB = -lm
then it should work.

Resources