autoconf & automake versus -O2 versus -O3 - autoconf

My configure.ac contains
AC_PROG_CXX
and my Makefile.am contains
AM_CXXFLAGS= -Werror -O3
and the resulting 'configure' script keeps on adding -O2 to the mix in addition to O3.
I have this suspicion that I'm supposed to do something in configure.ac to declare my preference for O3, but I can't find it in the doc. How do I tell it that I want to control the optimization level?

No, you are not supposed to add anything to configure.ac to indicate a preference for -O3. That sort of thing belongs in a user's CONFIG_SITE, not in configure.ac
However, if you insist on breaking the convention, you can do something like:
: ${CXXFLAGS=-Werror -O3}
Note that this line must appear before AC_PROG_CXX (or any macro that AC_REQUIRES it, such as LT_INIT, as that will cause AC_PROG_CXX to be emitted into the configure script before this line.)

The prior answer is correct in that it should be the installer's choice what flags are used. If you're still wondering where the -g -O2 comes from (likely), it is described at http://www.gnu.org/s/hello/manual/autoconf/C_002b_002b-Compiler.html.
That page does suggest "If your package does not like this default, then it is acceptable to insert the line ‘: ${CXXFLAGS=""}’ after AC_INIT and before AC_PROG_CXX to select an empty default instead."

Related

How to pass arbitrary compiler CFLAGS with Scons from the command line without custom code?

Is there a way to write something like:
scons CFLAGS='-fsanitize=address -fsanitize=thread'
which would just work with a minimal script:
env = Environment()
env.Program(target='main.out', source=['main.c'])
without changing that script?
I know how to do it by modifying the script with AddOption + env.Append(CCFLAGS but I'm wondering it it is possible without changing the code to explicitly support it.
I ended up going with:
env = Environment()
env.Append(CCFLAGS='-Werror')
env.Append(CCFLAGS=ARGUMENTS.get('CCFLAGS', ''))
env.Program(target='main.out', source=['main.c'])
which can be used as:
scons CCFLAGS='-Wall -pedantic'
and will compile as:
gcc -o main.o -c -Werror -Wall -pedantic main.c
You likely want to keep the env.Append(CCFLAGS=ARGUMENTS.get('CCFLAGS', '')) line as the very last change made to CCFLAGS, since this will allow overriding the defaults on the command line: GCC tends to just use the last value seen as the actual one.
TODO: how to make it work with Variables? This would be nicer since we can get more error checking and the help message generation:
variables = Variables(None, ARGUMENTS)
variables.Add('CCFLAGS', 'my help', '')
env = Environment(variables)
env.Append(CCFLAGS='$CCFLAGS')
env.Append(CCFLAGS=['-Werror'])
env.Program(
source=['main.c'],
target='main.out',
)
Help(variables.GenerateHelpText(env))
but this fails due to bad quoting:
gcc -o main.o -c "-Wall -pedantic" -Werror main.c
This is not possible by design (without explicitly changing the build scripts). From the answer to #1 of the most-frequently-asked questions in our FAQ:
SCons does not automatically propagate the external environment used
to execute 'scons' to the commands used to build target files. This is
so that builds will be guaranteed repeatable regardless of the
environment variables set at the time scons is invoked. This also
means that if the compiler or other commands that you want to use to
build your target files are not in standard system locations, SCons
will not find them unless you explicitly set the PATH to include those
locations.

Understanding the role of automatic variables in make/makefile

I've recently started learning about make/makefiles and some of its associated concepts. I have thus far created some basic versions, with targets, dependencies, actions, etc. However, I have been unable to make sense of what automatic variables are in this context, their utility, or how to use them.
I've done a lot of research on this topic. However, I haven't been able to locate any satisfying material. It seems that the most reputable source of information is this GNU page. However, I still do not understand exactly what automatic variables are, what their utility is, or how I can practically use them in my makefiles.
I am interested to find out what they are, what their utility is, and how I can practically use them.
Automatic variables are simply variables for which the value is generated by Make, rather than having to be set explicitly.
If you take a look at existing Makefiles (pick your favorite open source project!), you'll find lots of practical examples to help you out. A common one looks something like this:
%.o: %.c
gcc -c -o $# $<
This is a pattern rule that says "to build a file named <something>.o, which depends on <something.c>, use the command gcc -c -o $# $<. $# is an automatic variable that evaluates to the target of the rule, and $< is an automatic variable which evaluates to the first prerequisite of the rule. These automatic variables are critical to this sort of pattern rule; they allow you to run make foo.o or make bar.o and have the appropriate values substituted into the command line. E.g., if you type make foo.o, Make will try to run:
gcc -c -o foo.o foo.c
Or consider this example from the git Makefile:
strip: $(PROGRAMS) git$X
$(STRIP) $(STRIP_OPTS) $^
This is used to strip symbol information from object files. It needs to operate on all of the prerequisites, so it uses $^, which evaluates to...a space-separated list of all the prerequisites.

Using AM_INIT_AUTOMAKE parameters and configure script command line parameters

Is it possible to use both command line parameters to the configure script, ala:
../configure CXXFLAGS=-O0 -g -foo -bar -bat
while simultaneously keeping any options that are passed to AM_INIT_AUTOMAKE in the configure.ac file? e.g.:
AM_INIT_AUTOMAKE([-Wall -Werror])
My desired result is that ALL of the above flags are passed along, e.g.:
-O0 -g -foo -bar -bat -Wall -Werror
It appears that specifying CXXFLAGS on the command line either ingores or overwrites what is passed into AM_INIT_AUTOMAKE. If anyone knows of a way to do the union of the two sets, that would be extremely helpful. Thx!
The -W warning categories options have nothing to do with C[XX]FLAGS. These are command line arguments used when invoking automake.
Conversely, the AM_INIT_AUTOMAKE options like -Wall don't affect the compiler flags. It's just the decision to use these switch names that is resulting in the confusion. They have a similar meaning, e.g., -Werror will treat automake warnings as errors, but are totally unrelated.
In short, you have to pass -Wall, etc., in C[XX]FLAGS to influence the compiler. And add -Wall to AM_INIT_AUTOMAKE to enable all warning categories when automake is invoked.

Symbols from convenience library not getting exported in executable

I have a program, myprogram, which is linked with a static convenience library, call it libconvenience.a, which contains a function, func(). The function func() isn't called anywhere in myprogram; it needs to be able to be called from a plugin library, plugin.so.
The symbol func() is not getting exported dynamically in myprogram. If I run
nm myprogram | grep func
I get nothing. However, it isn't missing from libconvenience.a:
nm libconvenience/libconvenience.a | grep func
00000000 T func
I am using automake, but if I do the last linking step by hand on the command line instead, it doesn't work either:
gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/libconvenience.a `pkg-config --libs somelibraries`
However, if I link the program like this, skipping the use of a convenience library and linking the object files that would have gone into libconvenience.a directly, func() shows up in myprogram's symbols as it should:
gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/*.o `pkg-config --libs somelibraries`
If I add a dummy call to func() somewhere in myprogram, then func() also shows up in myprogram's symbols. But I thought that --export-dynamic was supposed to export all symbols regardless of whether they were used in the program or not!
I am using automake 1.11.1 and gcc 4.5.1 on Fedora 14. I am also using Libtool 2.2.10 to build plugin.so (but not the convenience library.)
I didn't forget to put -Wl,--export-dynamic in myprogram_LDFLAGS, nor did I forget to put the source that contains func() in libconvenience_a_SOURCES (some Googling suggests that these are common causes of this problem.)
Can somebody help me understand what is going on here?
I managed to solve it. It was this note from John Calcote's excellent Autotools book that pointed me in the right direction:
Linkers add to the binary product every object file specified explicitly on the command line, but they only extract from archives those object files that are actually referenced in the code being linked.
To counteract this behavior, one can use the --whole-archive flag to libtool. However, this causes all the symbols from all the system libraries to be pulled in also, causing lots of double symbol definition errors. So --whole-archive needs to be right before libconvenience.a on the linker command line, and it needs to be followed by --no-whole-archive so that the other libraries aren't treated that way. This is a bit difficult since automake and libtool don't really guarantee keeping your flags in the same order on the command line, but this line in Makefile.am did the trick:
myprogram_LDFLAGS = -Wl,--export-dynamic \
-Wl,--whole-archive,libconvenience/libconvenience.a,--no-whole-archive
If you need func to be in plugin.so, you should try and locate it there if possible. Convenience libraries are meant to be just that -- a convenience to link to an executable or lib as an intermediate step.

Setting per-file flags with automake

Is there a way set flags on a per-file basis with automake?
In particular, if I have a c++ project and want to compile with -WAll all the files except one for which I want to disable a particular warning, what could I do?
I tried something like:
CXXFLAGS = -WAll ...
bin_PROGRAMS = test
test_SOURCES = main.cpp utility.cpp
utility_o_CXXFLAGS = $(CXXFLAGS) -Wno-unused-value
but it didn't work.
EDITED: removed reference to automake manual, which was actually misleading (thanks to Douglas Leeder).
You can't do this with automake... but can do with make =) Add following line to your Makefile.am:
utility.$(OBJEXT) : CXXFLAGS += -Wno-unused-value
See GNU Make documentation : Target-specific Variable Values for details.
Automake only supports per-target flags, while you want per-object flags. One way around is to create a small library that contains your object:
CXXFLAGS = -Wall ...
bin_PROGRAMS = test
test_SOURCES = main.cpp
test_LDADD = libutility.a
noinst_LIBRARIES = libutility.a
libutility_a_SOURCES = utility.cpp
libutility_a_CXXFLAGS = $(CXXFLAGS) -Wno-unused-value
You've got confused - that section is referring to options to automake itself.
It's a way of setting the automake command-line options:
-W CATEGORY
--warnings=category
Output warnings falling in category. category can be one of:
gnu
warnings related to the GNU Coding Standards (see Top).
obsolete
obsolete features or constructions
override
user redefinitions of Automake rules or variables
portability
portability issues (e.g., use of make features that are known to be not portable)
syntax
weird syntax, unused variables, typos
unsupported
unsupported or incomplete features
all
all the warnings
none
turn off all the warnings
error
treat warnings as errors
A category can be turned off by prefixing its name with ‘no-’.
For instance, -Wno-syntax will hide the
warnings about unused variables.
The categories output by default are ‘syntax’ and ‘unsupported’.
Additionally, ‘gnu’ and ‘portability’
are enabled in --gnu and --gnits
strictness.
The environment variable WARNINGS can contain a comma separated list of
categories to enable. It will be taken
into account before the command-line
switches, this way -Wnone will also
ignore any warning category enabled by
WARNINGS. This variable is also used
by other tools like autoconf; unknown
categories are ignored for this
reason.
The per-file listed in section 17 refers to per-Makefile not source file.
I'm not aware of any per-source file flag setting, but you can set the option for each result binary with:
binaryname_CXXFLAGS

Resources