autotools: Enable compiler warnings - c

for an autotools-based C project, I'd like to get some more warnings from the compiler (e.g. at least -Wall in CFLAGS). What is the prefered way to enable compiler flags without breaking anything? Is there a m4 macro that tests if a given compiler flag is understood by the compiler?
With such a macro I could do
TEST_AND_USE(-Wall -Wextra <other flags>)
Thanks

You can just use AC_TRY_COMPILE:
AC_MSG_CHECKING(whether compiler understands -Wall)
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wall"
AC_TRY_COMPILE([],[],
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no)
CFLAGS="$old_CFLAGS")
2015 addition: AC_TRY_COMPILE is now deprecated, instead you should use AC_COMPILE_IFELSE:
AC_MSG_CHECKING(whether compiler understands -Wall)
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wall"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no)
CFLAGS="$old_CFLAGS")

Don't bother changing the configure.ac at all. Just call ./configure with the CFLAGS you care about:
./configure CFLAGS='-Wall -Wextra -O2 -g'

Widely used is the attributes.m4 CC_CHECK_CFLAG_APPEND macro from the xine project. Although, you often find variants (since it's quite simple) written directly in configure.ac

I do this:
# debug compilation
AC_ARG_ENABLE(debug,
AC_HELP_STRING(--enable-debug, [Debug compilation (Default = no)]),
enable_debug=$enableval, enable_debug=no)
if test "$enable_debug" = "yes" ; then
CFLAGS="$CFLAGS -g -O0 -Wall -Wno-uninitialized"
CXXFLAGS="$CXXFLAGS -g -O0 -Wall -Wno-uninitialized"
fi
it is a low-tech solution, but you do not have to accommodate all compilers

Related

What are compiler flags for?Why won't my code compile?

I wrote a code in C in Ubuntu which checks for balanced brackets in the input given.I compiled it using gcc compiler and I am getting the correct output.This is actually a part of an online course and they are asking me to use the compiler flag
gcc -pipe -O2 -std=c11 filename -lm
I don't think I understand what I am supposed to do so I tried compiling using this flag and my code is not compiling. My question is if my code compiles when I do
gcc filename.c
why isn't it compiling when I do
gcc -pipe -O2 -std=c11 filename -lm
The error message I am getting is :
cc1plus: warning: command line option ‘-std=c11’ is valid for C/ObjC but not for C++
The reason is the file ending. A capital C is interpreted as a C++ file. The solution is to just rename the file like this:
mv filename.C filename.c
My question is if my code compiles when I do gcc filename.C why isn't it compiling when I do gcc -pipe -O2 -std=c11 <filename> -lm
See above. But there are some situations where it would not solve everything. While C11 gives some extensions to previous versions, it's not 100% backwards compatible.
-std=c11 is a correct option
however you need at least gcc 4.7 or higher to have this option
By "<filename>" they mean to substitute in the name of the file you want to compile. Including the literal string "<filename>" will not work.

What does `-Wextra` flag mean in clang compiler?

What is the meaning of -Wextra in clang compiler flag?
I was curious what does all the flags such as -Wall, -Werror means. I was able to find answers for others, but not -Wextra.
clang -Wall -Wextra -Werror
-Wextra flag is not specific to just the clang compiler, it is documented in the GCC Compiler as well. Basically, -Wall enables all (common) warning flags but this excludes many flags.
Some of these, notably -Wempty-init-stmt, -Wignored-qualifiers, -Winitializer-overrides, -Wmissing-field-initializers, -Wmissing-method-return-type, -Wnull-pointer-arithmetic, -Wsemicolon-before-method-body, -Wsign-compare, -Wunused-parameter are covered by -Wextra instead.
You can find out more about what each of these mean in the documentation.
-Wextra compiler flag is not just in clang but also in gcc. According to the gcc docs:
This enables some extra warning flags that are not enabled by -Wall. This option used to be called -W. The older name is still supported, but the newer name is more descriptive.
Source:
Clang docs
GCC docs

Which rules should use CFLAGS in GNU make

In my makefile for a C project, I have set the CFLAGS variable as follows -
CFLAGS=-ansi -pedantic -Wall -Wextra -O2 -isystem $(SQLITEDIR)
I expected this variable to be used in the rule for building object files since the flags affect the compilation step
However, in the GNU make manual
https://www.gnu.org/software/make/manual/make.html#Using-Implicit
I see the following example -
foo : foo.o bar.o
cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)
I think this is a rule for the linking step so I understand it why it include LDFLAGS, but what is the purpose CFLAGS here?
(I am guessing that you are using GNU make on some Linux system)
You are right in your use of CFLAGS (but I would add -g there). But I am not sure you need -isystem $(SQLITEDIR), it probably can be -I $(SQLITEDIR) instead. The -isystem directory option to GCC is rarely useful.
Read first the documentation about Invoking GCC, assuming you are using the GCC compiler. BTW, you could have CC= gcc in your Makefile. If your compiler is not GCC but something else (e.g. Clang/LLVM) read its documentation.
Then, run make -p to understand the builtin rules of your GNU make (there are many of them). You'll find out that many builtin rules are using CFLAGS etc. And that is why it is simpler to have a CFLAGS variable in your Makefile; if possible, take advantage of some builtin rules known to make.
BTW, you could avoid using any builtin rules and variables, but that is poor taste.
The POSIX standard defines some options understood by cc and by make (and some minimal rules for make). Both GCC and GNU make have much more. Read documentation of GNU make.
CFLAGS usually contain some (optimization or other) flags (e.g. -O or -g, or -pthread) which are also relevant at the linking step (assuming you link with gcc, which will invoke ld). That is why you usually link using gcc (as $(CC) in your recipe) with both LDFLAGS and CFLAGS.
You could use make --trace or even remake (as remake -x) to debug your Makefile.

gcc linking object files with warning/optimization flags

We are compiling a piece of software using generics where files are first made into object files, they are built like so:
arm-unknown-linux-gnu-gcc -c -O2 -Wstrict-prototypes -Wdeclaration-after-statement -fsigned-char -I/opt/tm-sdk/include -mlittle-endian -Wno-trigraphs -fno-strict-aliasing -fno-omit-frame-pointer -march=armv4 -mtune=arm9tdmi -Wall -Wextra -o src/flex.o src/flex.c
...
arm-unknown-linux-gnu-gcc -c -O2 -Wstrict-prototypes -Wdeclaration-after-statement -fsigned-char -I/opt/tm-sdk/include -mlittle-endian -Wno-trigraphs -fno-strict-aliasing -fno-omit-frame-pointer -march=armv4 -mtune=arm9tdmi -Wall -Wextra -o src/flexdb.o src/flexdb.c
Then they are linked with:
arm-unknown-linux-gnu-gcc -o flex src/flex.o src/flexdb.o src/flexio.o src/flexprotocol.o src/flexsettings.o src/flexstate.o -L/opt/tm-sdk/lib -ltag -lrt -ltmreader -lsqlite3 -lsha1
My questions is:
Do we need to include optimization and warning flags during linking? Would it do anything if -Wall, -Wextra, and -O2 were included when creating the flex binary from the object files?
Edit: Clarifying meaning based on feedback.
Do we need to include optimization and warning flags during this final stage of compilation?
Of course you don't need to include them for the link stage. You already know that, because you don't include them. But I think what you really want to know is ...
Would it do anything if -Wall, -Wextra, and -O2 were included when building the flex binary from object files.
All or almost all warnings are generated during the compilation stage. I don't off-hand know any exceptions, but it's conceivable that there are some. Thus, it's possible that passing warning-related flags during linking would trigger warnings that otherwise you would not receive. But that shouldn't affect the compiled binary in any way.
Optimization is different. There are optimizations that can be performed at link time, but that might not be performed at the default optimization level. Omitting optimization flags from the link command should not break your build, but including them may result in a binary that is faster and / or smaller.
Overall, I see no good reason to avoid passing the same warning and optimization flags during the link step that you do during the compilation steps. If you wish, it's not harmful to pass preprocessor-specific flags (e.g. -D) as well, as they'll just be ignored during linking. I presume that all this is managed by make, so it's not like you actually need to type out the options every time.
NO You're just calling the linker with the final call to gcc and -W and -O flags are for the compiler.
-Wall is primarily a preprocessor option, but there is also a reference for the libraries. See here
-Wextra appears to be strictly a c++ preprocessor option. See here
-O2 is a compiler optimization level setting. See here
So to answer your precise question, only -Wall would possibly help during your link step. The other two would not. You could test this by building with and without these options, seeing if any additional output is created in the case of warnings and if the code size or execution time differed between builds.

Running ./configure with -Wall leads to libraries not being found

I'd like to use -Wall and -Werror as flags for gcc in an autotools project, but I don't want to put them in my configure.ac.
As such, I tried using ./configure CFLAGS='-Wall -Werror', only to get an error from one of my AC_SEARCH_LIBS macro calls:
AC_SEARCH_LIBS([pow], [m], , AC_MSG_ERROR([Could not find standard math library.]))
Resulting error when running configure with the CFLAGS added:
configure: error: Could not find standard math library.
What am I doing wrong here? Configuration works fine without the CFLAGS variable set.
As you now know, elevating the compile warnings to errors confuses ./configure.
What you can do is pass custom CFLAGS at make time:
$ ./configure
$ make CFLAGS='-O2 -g -Wall -Wextra -Werror'
The other option is William Pursell's approach: add an option to ./configure to turn on -Werror if supported:
(configure.ac)
AC_ARG_ENABLE([werror],
[AS_HELP_STRING([--enable-werror], [Use -Werror #<:#no#:>#])],
[:],
[enable_werror=no])
AM_CONDITIONAL([ENABLE_WERROR], [test "$enable_werror" = yes])
(Makefile.am)
if ENABLE_WERROR
AM_CFLAGS += -Werror
endif

Resources