Correcting The Gcc Command Line Ordering Using Automake

Correcting the GCC command line ordering using Automake

The solution turned out to be the difference between LDFLAGS and LDADD. In short LDFLAGS is added before the object files on the command line and LDADD is added afterwards. Thus, changing Makefile.am to the following solved the problem:

CFLAGS=-Wall
bin_PROGRAMS=test
test_CFLAGS=$(GLIB_CFLAGS)
test_LDADD=$(GLIB_LIBS)
test_SOURCES=test.c

It only took tracking down a GCC developer at work to solve. Also, this example I provided is rather poor because test has a defined meaning in some contexts of autotools.

automake output binaries bigger than the command-line compiled bins

Just invoke make install-strip when you install the binaries and install will strip them during the install process.

Autotools build fails while linking

Changing main_LDFLAGS to main_LDADD solved the problem.

Correcting the GCC command line ordering using Automake

How do I link a shared library with --as-needed with automake?

You can fix that just for your project by modifying the ltmain.sh script in your project sources. You can even add it as part of autotools bootstrapping, as in:
https://meego.gitorious.org/tracker/tracker/commit/cf2ca3414aeba146dceacc5ecd84765f4c08a06f

How to set compiler-specific flags with autotools

AM_CXXFLAGS isn't something you should AC_SUBST. It is reserved for use by automake. If you look at the Makefile generated for a C++ target, you will find definitions for CXXCOMPILE and LTCXXCOMPILE, which always include the AM_CXXFLAGS variable.

You want to add the (conditional) compiler flag to AM_CXXFLAGS or to libfoo_la_CXXFLAGS. The former will affect all C++ compilations, and the latter just the per-library compilations. So it's just a matter of getting SPECIFIC_CXXFLAGS right in configure.ac.

AC_PROG_CXX
...
FOO_SPECIFIC_CXXFLAGS=;
if `$CXX -v 2>&1 | grep 'gcc version' >/dev/null 2>&1` ; then
FOO_SPECIFIC_CXXFLAGS="--param max-vartrack-size=100000000"
fi

AC_SUBST(FOO_SPECIFIC_CXXFLAGS, $FOO_SPECIFIC_CXXFLAGS)

The GXX test is insufficient as autoconf just tests for the __GNUC__ macro (AFAIK), so clang++ will set: GXX=yes

The problem is, there isn't a portable way of detecting command line options that are unknown. Intel's icc -v will even reproduce the gcc version string. So you might have to add another filter, like: | grep -v 'icc'

You could optionally check that the flag works as advertised before AC_SUBST, but this doesn't really help if the compiler only generates a warning:

saved_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $FOO_SPECIFIC_CXXFLAGS"

AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],,[FOO_SPECIFIC_CXXFLAGS=;])
AC_LANG_POP([C++])
CXXFLAGS="$saved_CXXFLAGS"

Then in Makefile.am:

AM_CXXFLAGS = $(FOO_SPECIFIC_CXXFLAGS)

or:

libfoo_la_CXXFLAGS = $(FOO_SPECIFIC_CXXFLAGS)

Makefile seems to be compiling files in the wrong order

From a purely technical perspective the line making the .o is erroneous in that it had:

.cpp.o:
$(LD) $(CFLAGS) $< -o $@

This would cause the production of a file intended to be linked that has already been linked; therefore a bunch of extra values would be injected into .o file which would not be expected when it comes to the linking step:

$(EXECUTABLE): $(OBJECTS)
$(LD) $(LDFLAGS) $(OBJECTS) -o $@

So, let's get the terminology for the makefiles in order - compiling is using either the C or C++ compiler, which generally involves using the variables CC or CXX, so we're just compiling the .cpp files into .o files, so we should compile using the C++ compiler, and the C++ flags:

.cpp.o:
$(CXX) $(CXXFLAGS) $< -o $@

Making the changes to the Makefile doesn't cause the already built files to suddenly become invalid (unless we made all the files depend on the Makefile), so you need to clean up what's already been compiled - you would have had a .o file that had been built incorrectly, an invocation of make clean will remove this .o file so that a subsequent invocation of make would rebuild it.

As for some stylistic items for the Makefile; you generally do:

  • CFLAGS == flags for the C compiler only
  • CXXFLAGS == flags for the C++ compiler only
  • CPPFLAGS == flags for the C preprocessor only

You can use make -p to dump out the default database for make, which would indicate it's default compile and link lines for various file types, and it shows:

.cpp.o:
# Builtin rule
# Implicit rule search has not been done.
# Modification time never checked.
# File has not been updated.
# recipe to execute (built-in):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<

COMPILE.cpp = $(COMPILE.cc)

COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

You can build on these built-in rules, in order to reduce the amount of code you need to write in your makefile

In very simple gtk2 c app, problem setting up gnu build tools

Two issues in your configure.ac file. First, the syntax of your AM_INIT_AUTOMAKE invocation is 10 year old, I suspect you copied it from a very old tutorial (hint: the Automake manual has a tutorialish introduction). You've already passed the package and version to AC_INIT, there is no need to repeat that in AM_INIT_AUTOMAKE. Second, the list of files passed to AC_CONFIG_OUTPUT should be a space-separated list given as first argument.

In other words, your configure.ac should look like

AC_PREREQ([2.63])
AC_INIT([app], [0.1], [your@email])
AM_INIT_AUTOMAKE([-Wall])
AC_CONFIG_SRCDIR([src/main.h])
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT

Note there is no coma on the AC_CONFIG_FILES line.

The -Wall option will cause automake to output more warnings (this really is an automake option, not a gcc option), it's probably safer if you discover these tools.

This should fix your configure problem. Then I suspect you'll probably have to split your app_LDADD line into app_CPPFLAGS and app_LDFLAGS.

Can't make automake to use C++11

A quick test shows that everything is working correctly for me, with a similar configuration, so you're going to have to figure out what's going on with your Makefile simply by rolling up your sleeves, looking into your final Makefile.

Look inside the automake-d Makefile. You should find somewhere inside it, the final build rule for .cpp.o. Search for ".cpp.o". It should look something like this:

.cpp.o:
$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po

After verifying this, the next step is to look at what your CXXCOMPILE macro is defined to. It should look something like this:

CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)

And that's your AM_CXXFLAGS variable being used. Finally, confirm how it's defined in the actual Makefile.

In my case, for my simple test, it was simply:

AM_CXXFLAGS = -std=gnu++11

In my case, it was just that, in your case, obviously you'll have your other flags in there.

That's it. The automake-d Makefile is obviously quite large, and looks intimidating, but when you get down to it, it's not very complicated at all.

It's going to be one of two things. Either another part of your Makefile.am clobbers the value of AM_CXXFLAGS, or the CXXCOMPILE macro is clobbered. One thing about automake, is that it generally doesn't complain if a macro or a variable is redefined. It'll simply generate the final Makefile using the final value of the variable. So, I would guess that somewhere later, in your Makefile.am, you set AM_CXXFLAGS to something else, without being aware of it here.

Note: the actual macros often get tweaked, with each successive version of automake, so yours may look slightly different, but the general idea should be the same. The .cpp.o build rule runs the CXXCOMPILE macro, which uses AM_CXXFLAGS.



Related Topics



Leave a reply



Submit