Makefile.am/Configure.ac Conditional Environment Variable Check - c++

I am trying to enable and disable compile flags for gcov in C++ on Linux. I do not want to have the gcov flags set at all times. I only want them set when I am testing the software. The environment variable I am checking is called TESTENABLED.
In my configure.ac file I have the following line:
AM_CONDITIONAL([ENABLEGCOV],[test x$TESTENABLED = xtrue])
In my Makefile.am file I have the following lines:
if ENABLEGCOV
AM_CXXFLAGS = -Wall -fPIC -fprofile-arcs -ftest-coverage
else
AM_CXXFLAGS = -Wall
endif
However when I build my program I notice that it is not setting AM_CXXFLAGS correctly. So none of my gcov .gcno/.gcda files are being generated. Does anyone see what I am doing wrong?

Do you have your environment variable set to true, or probably to some other truish-value (e.g. 1)?
In any case, the usual way would be add a flag to configure that turns on a certain feature. The following configure.ac snippet adds a --enable-gcov flag to configure; it will also do a printout whether it has enabled gcov or not:
AC_ARG_ENABLE(gcov,[AS_HELP_STRING([--enable-gcov], [enable coverage test])])
AC_MSG_CHECKING([whether to enable gcov])
AS_IF([test "x${enable_gcov}" = "xyes" ], AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]))
AM_CONDITIONAL([ENABLEGCOV],[test "x${enable_gcov}" = "xyes"])
I also find Makefile.am more easy to read by just adding flags to CXXFLAGS if a certain condition is met:
AM_CXXFLAGS = -Wall -fPIC
if ENABLEGCOV
AM_CXXFLAGS += -fprofile-arcs -ftest-coverage
endif

Related

What does it means #CPPFLAGS# in Makefile.in?

I have a Makefile.in file that generate a Makefile.am by configure. After that with automake the Makefile.am create the Makefile.
Now i want to add a define in the geneated Makefile. The problem is that in the generated Makefile i found a list of flags in variable CPPFLAGS, but in the definition of CPPFLAGS in the Makefile.in i found only a line that is write in the following way:
CPPFLAGS = #CPPFLAGS#
What does it means #CPPFLAGS# ? And how i can set a new flag in the generated Makefile?
CPPFLAGS stands for C Pre Processor flags.
You can set it as an environmental variable or via the commandline:
CPPFLAGS="-g -Wall -O0" automake
or
CPPFLAGS="-g -Wall -O0" make
From the gnu Make manual:
CPPFLAGS
Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).
The string #CPPFLAGS# is expanded by the configure script to be the value of CPPFLAGS at the time configure is executed. In other words, if you run configure CPPFLAGS=foo, then #CPPFLAGS# will be expanded to the string foo.
Automake was run long before configure is invoked. All automake did was add the string #CPPFLAGS# to Makefile.in when it built that file.
As the project maintainer, you should not edit these values. This is the mechanism by which the user is able to add flags to the build at configure time.
If you want to add flags, you should assign to AM_CPPFLAGS in Makefile.am. But chances are you don't really want to do that. It's hard to say, and will depend on what flags you think you want to add.

Create Makefile to be used in different environments for C++

I would like to compile and run my program in two different environments. The libraries in both environments are installed on slightly different places, resulting in different makefile-lines:
In makefile A:
CXXFLAGS=-I$(DIR) -flto -fopenmp -O3 -g -march=native -std=gnu++17 -c -I/opt/interp2d/include -std=c++17 -I/opt/splinter/include -I/usr/include/eigen3
In makefile B:
CXXFLAGS=-I$(DIR) -nostindc++ -I~/local_opt/eigen/include/eigen3/ -I~/local_opt/boost/include -I~/local_opt/armadillo/include -flto -fopenmp -O3 -g -march=native -std=gnu++17 -c -I~/local_opt/interp2d/include -std=c++17 -I~/local_opt/splinterp/include -I/usr/include/eigen3
My problem now is that I am developing the program on the first machine, using makefile A, but also deploying it on the second machine. The deployment is done using git.
Every time I do a git pull on the second machine, I have to fix all the paths in the makefile in order to compile the program properly. Nevertheless I still would like to include the makefile in the git repository in order to keep both makefiles at the same level regarding compiling flags and linked libraries.
Thus, is there an easier way to still sync the makefile via git, while using different paths for the libraries and includes?
I think you could solve your problem by conditionally setting the variable CXXFLAGS in a common file (e.g.: config.mk) and by including that file in your makefiles.
The value used for setting the CXXFLAGS variable could, for example, depend on the value of the environment variable HOST:
ifeq ($(HOST),A)
CXXFLAGS = ... # for machine A
else # B
CXXFLAGS = ... # for machine B
endif
Then, include this config.mk makefile in both makefileA and makefileB:
include config.mk
I like this answer, however, I thought I'd mention this for completeness: If you have a lot of different hosts you can do something to the effect of:
include HostConfig_$(HOST).mk
And then create HostConfig_A.mk and HostConfig_B.mk which set host specific flags (Be it directories, etc). This is useful if you are managing a large project with lots of different host-specific variables.
As well, (for smaller projects), you could do something to the effect of:
CXX_INCLUDES_A = ...
CXX_INCLUDES_B = ...
CXX_FLAGS := -I$(DIR) -flto -fopenmp -O3 -g -march=native -std=gnu++17
CXX_FLAGS += $(CXX_INCLUDES_$(HOST))
The traditional answer to this problem is a configure script (see automake, autoconf for widely used framework). After checking out the source you run ./configure --with-eigen=~/local_opt/eigen/include/eigen3/ and it will adjust your Makefiles accordingly (usually generates Makefile from Makefile.in and only Makefile.in is in git).
Note: Properly done you only need to run configure on the first checkout, not on updates. make can generate Makefile again automatially as needed.

C++ Access Autoconf Variable Datadir

I am creating a program called spellcheck, and I'm using autoconf and automake to create a build system for it. The program relies on the dictionary 'english.dict', which is in the data directory (based on whatever prefix the user selected). I want the data directory path accessible by spellcheck, so I created a custom variable that contained its value:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT(libspellcheck, 1.25, corinthianmonthly#hotmail.com)
AC_OUTPUT(Makefile libspellcheck/Makefile spellcheck/Makefile man/Makefile)
AC_CONFIG_SRCDIR([])
AC_CONFIG_HEADERS([config.h])
AC_DEFINE_UNQUOTED([DATA_PATH], ["$pkgdatadir"],"DData Directory Path")
AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_CXX
AC_PROG_RANLIB
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h,iostream,fstream,string,stdio.h,sstream,cctype,algorithm,boost/algorithm/string.hpp])
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_TYPE_SIZE_T
# Checks for library functions.
AC_OUTPUT
However, in the config.h file, this value is blank:
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* "Description" */
#define DATA_PATH ""
...
I tried changing $pkgdatadir to $datadir, but I got the same result. What am I doing wrong, or is what I am trying to achieve impossible?
EDIT: I redefined the variable in my Makefile.am for spellcheck:
AM_CFLAGS = -DDATA_PATH=\"$(pkgdatadir)\" -m32 -Wall
bin_PROGRAMS = spellcheck
pkgdata_DATA = english.dict
spellcheck_SOURCES = spellcheck.cpp meta.cpp
spellcheck_LDADD = ../libspellcheck/libspellcheck.a
But now it complains about DATA_PATH being nonexistant:
spellcheck.cpp:4:22: error: 'DATA_PATH' was not declared in this scope
#define DEFAULT_DICT DATA_PATH "english.dict"
Because now it seems to be ignoring all CFLAGS:
g++ -DHAVE_CONFIG_H -I. -g -O2 -MT spellcheck.o -MD -MP -MF .deps/spellcheck.Tpo -c -o spellcheck.o spellcheck.cpp
It turns out that I needed to use AM_CPPFLAGS rather than CFLAGS.

Qt and gcov, coverage files are not generated

I am trying to obtain code coverage for a component I am writing for the Arora browser, that is written using C++ and Qt framework.
I am not able to use the gcov program, neither under Gnu/Linux nor Mac Os X. I tried everything I was able to find on the Internet, also by forcing things automatically editing the Makefile generated by the .pro file.
Can somebody help me please? This is my very simple pro file:
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
LIBS += -lgcov
QMAKE_CXXFLAGS += -g -fprofile-arcs -ftest-coverage -O0
QMAKE_LDFLAGS += -g -fprofile-arcs -ftest-coverage -O0
include(../autotests.pri)
# Input
SOURCES += tst_quickview.cpp
HEADERS +=
The Makefile does correctly contain the flags. I also tried the --coverage option. But nothing happens. When I run the executable, no gcov files are generated. There are no errors and no warnings. I am using the QTestLib framework.
Thank you
Atleast in cases where i've had similar issues, the problem has been in directory structures.
First issue was/is that in order to generate proper .gc* files during execution, compiler cache needs to be disabled. I never really debugged the issue but now, i'd assume that the gconv files where infact placed on the compiler cache folder and during the execution of the coverage instrumented binaries, binary was not able to idenfify where new datafiles should be generated.
Second issue is/was that i had to run the tests in the same directory structure as they where compiled in. For example, if i had compiled the application in "/home/foo/src/myproject/" and all its subdirectories .. The execution has to happen in that same directory structure or the datafiles won't get generated..
At least you should use
QMAKE_LFLAGS += -g -fprofile-arcs -ftest-coverage -O0
instead of
QMAKE_LDFLAGS += -g -fprofile-arcs -ftest-coverage -O0
I'm not sure if that will fix your problem but QMAKE_LDFLAGS is not going to do anything useful.

Set debugging macro conditionally with make

In my C++ project, I have a convention where whenever the macro DEBUG is defined, debugging printf-esque statements are compiled into the executable.
To indicate whether or not I want these compiled into the executable, I normally would pass the macro name to gcc with the -Dmacro option. So, in the Makefile I (currently) have:
CXXFLAGS += -g -I ../ -Wall -Werror -DDEBUG
However, this is not very flexible; if I didn't want debug statements in my final program, I'd have to modify the Makefile to remove the -DDEBUG.
Is there a way to modify the Makefile such that I can conditionally select whether to compile with -D in the CXXFLAGS at compile time by passing in, say, another target name or a commandline switch? Not sure how'd I go about doing that.
You can conditionally define other variables based on the target in the makefile.
all: target
debug: target
debug: DEBUG=PLOP
target:
#echo "HI $(DEBUG)"
So now:
> make
HI
>
> make debug
HI PLOP
>
Append another variable that you can set from the CLI or environment
$ cat Makefile
CXXFLAGS += $(CLIFLAGS)
maintarget:
echo $(CXXFLAGS)
$ make CLIFLAGS=-DDEBUG
echo -DDEBUG
-DDEBUG
$
Consider this one:
http://users.softlab.ece.ntua.gr/~ttsiod/makefile.html
After meditating upon the make documentation, I tried putting this in my Makefile:
ifneq(,$(findstring d,$(MAKEFLAGS)))
CXXFLAGS += <... all normal options ...> -DDEBUG
else
CXXFLAGS += <... all normal options ...>
endif
Then, when you run make -d, -DDEBUG is set.
Now, mind you, it works, but I had to use a normal flag that make usually accepts (you can't make up your own). Using -d also spews (harmless) verbose make-level debugging statements to the screen. Which I really don't want; it obscures compile errors. But it does work.
I hope someone can come up with a better idea.