Adding a directory for the headers in a Makefile - include

Hello I would like to ask you, If someone knows how can I add a directory for the header files in the Makefile to avoid the error *.h not found, I have tried this option but does not work:
INC_PATH := -I /directory/to/add

At least for GNU make, try the implicit variable CFLAGS, as in:
CFLAGS=-I/directory/to/add

Although the goal is ultimately to affect the value of CFLAGS (as suggested by #unwind), it is often not a good idea to simply set the value of CFLAGS as it is often built out of many pieces. You have to understand the structure of the makefile, and the set of macros used.
[Added:
Eduardo asked: Can you post macros to do the same?
Yes, but whether they are helpful depends on how your makefiles are structured. Here's a moderately complex example from one of my makefiles.
CC = gcc -g
XFLAGS = -Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes \
-DDEBUG -Wredundant-decls
#CC = cc -g
#XFLAGS =
UFLAGS = # Always overrideable on the command line
DEPEND.mk = sqlcmd-depend.mk
INSTALL.mk = sqlcmd-install.mk
ESQLC_VERSION = `esqlcver`
OFLAGS = # -DDEBUG_MALLOC -g
OFLAGS = -g -DDEBUG -O4
PFLAGS = -DHAVE_CONFIG_H
OFILES.o = # rfnmanip.o # malloc.o # strdup.o # memmove.o
VERSION = -DESQLC_VERSION=${ESQLC_VERSION}
#INC1 = <defined in sqlcmd-depend.mk>
#INC2 = <defined in sqlcmd-depend.mk>
INC3 = /usr/gnu/include
INC4 = ${INFORMIXDIR}/incl/esql
INC5 = . #${INFORMIXDIR}/incl
INCDIRS = -I${INC3} -I${INC1} -I${INC2} -I${INC4} -I${INC5}
LIBSQLCMD = libsqlcmd.a
STRIP = #-s
LIBC = #-lc_s
LIBMALLOC = #-lefence
LIBRDLN = -lreadline
LIBCURSES = -lcurses
LIBPOSIX4 = -lposix4
LIBG = #-lg
LIBDIR1 = ${HOME}/lib
LIBDIR2 = /usr/gnu/lib
LIBJL1 = ${LIBDIR1}/libjl.a
LIBJL2 = ${LIBDIR1}/libjlss-${ESQLC_VERSION}.a
LIBTOOLS = ${LIBJL2} ${LIBJL1}
LDFLAGS = ${LIBSQLCMD} ${LIBTOOLS} -L${LIBDIR2} ${LIBG} ${LIBMALLOC} \
${LIBPOSIX4} ${LIBC} ${STRIP}
CFLAGS = ${VERSION} ${INCDIRS} ${OFLAGS} ${XFLAGS} ${PFLAGS} ${UFLAGS}
This a makefile for a program of mine called sqlcmd (a name chosen a decade and more before Microsoft created a command of the same name). I assume that the make program has a rule for compiling C code to object like:
${CC} ${CFLAGS} -c $*.c
and that the rule for linking a program from a set of object files listed in the macro OBJECTS looks like:
${CC} ${CFLAGS} -o $# ${OBJECTS} ${LDFLAGS}
As you can see, there are separately settable macros for the ESQLC_VERSION (the version of Informix ESQL/C in use, derived by default by runing a script esqlcver), then the include directories via INC1 to INC5 and INCFLAGS (there can be quite a lot of these, depending on platform), and optimizer flags (OFLAGS), extra flags (CFLAGS), user-defined flags (UFLAGS - an idiom I use in most of my makefiles; it allows the user to set UFLAGS on the make command line and add an extra flag to the build), and a bunch of library-related macros. This is what it takes for my development makefile to be tunable with minimal fuss to my development platform, which can be Linux, Solaris or MacOS X. For consumers of the program, there is a configure script generated by autoconf, so they don't have to worry about getting those bits right. However, that has a strong genetic resemblance to this code, including the UFLAGS option.
Note that many systems for makefile building have a mechanism for setting CFLAGS faintly similar to this - and simply assigning to CFLAGS undoes the good work done by the system. But you have to understand your makefile to be able to modify it sanely.
]

Related

How can I run two makefile targets such that the second uses the first's variables?

I am writing a makefile that has multiple targets for architectures and build types. When I call make I would like to be able to pass it two targets such as:
make x86 debug
Where the architecture target sets variables to be used by the build target. An architecture target might look like this:
.PHONY: x86
x86: NAME_PREFIX = x86_64_Linux
x86: TARGET_TRIPLE = x86_64-pc-linux-elf
x86: CC = gcc
x86: CFLAGS += -fomit-frame-pointer
First issue: If I run the two targets, make skips the first target since it does nothing but set variables.
$ make x86 debug
make: Nothing to be done for `x86'.
Second issue: Even if it would run the first target, my understanding is that the values won't be retained when make starts running the second target anyway.
For now, I'm using targets that set variables and add the build type target as a prerequisite at the end of the target body, but I would end up needing a target for every combination of architecture and build type.
.PHONY: x86_debug
x86_debug: NAME_PREFIX = x86_64_Linux
x86_debug: TARGET_TRIPLE = x86_64-pc-linux-elf
x86_debug: CC = gcc
x86_debug: CFLAGS += -fomit-frame-pointer
x86_debug: debug
Your second approach is better. But you don't need a target for every combination, if you use a consistent naming scheme, and use wildcard targets:
.PHONY: x86_% arm_% # etc
.PHONY: %_debug %_optimised # etc
x86_%: NAME_PREFIX = x86_64_Linux
x86_%: TARGET_TRIPLE = x86_64-pc-linux-elf
x86_%: CC = gcc
x86_%: CFLAGS += -fomit-frame-pointer
arm_%: NAME_PREFIX = ARM_LINUX
arm_%: TARGET_TRIPLE = arm-linux-eabi
arm_%: CC = arm-linux-gcc
%_debug: CFLAGS += -g
%_optimised: CFLAGS += -O3

Default link script in GNU Make

I have this very simple makefile:
P = hello_world.exe
OBJECTS = main.o
CFLAGS = -g -Wall -O3
LDLIBS =
CC = clang
$(P): $(OBJECTS)
When I run make it will compile main.c but it will not link to hello_world.exe. Shouldn't that be happening automatically?
My environment is cygwin 64bit.
The output of make -p is here: http://pastebin.com/qbr0sRXL
There's no default rule for .exe files that I'm aware of (or can find in that output).
You'll need to write one yourself.
If your output was hello_world and you had a hello_world.c/hello_world.cpp source file and also a main.c/main.cpp file then your makefile as written would work I believe (since the default %: %.o rule would apply and your added prerequisite would be added to the hello_world prerequisite list).

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.

Make: Override a flag

I was a little confused with the responses to Quick way to override -Werror flag?
So I ask my specific question here.
I have multiple Makefiles working together and CFLAGS has been set along the way to (-Werror -Wall .. and many others)
But in one of the Makefiles, I wish that the errors not be treated as warnings and so I would like to remove -Werror flag.
What would be the best way to achieve this, so that only for this Makefile, -Werror flag is removed and for the others normal execution takes place?
Thanks,
Sunny
The right way to do this is with the filter-out function.
Put
CFLAGS := $(filter-out -Werror,$(CFLAGS))
in the Makefile where you want to override this, and the -Werror part of CFLAGS will be removed in that Makefile.
You can even use this to override flags for a single target by using target-specific variable values:
CFLAGS = -Werror
all: foo bar
foo:
echo cc $(CFLAGS) -o $#
bar: CFLAGS := $(filter-out -Werror,$(CFLAGS))
bar:
echo cc $(CFLAGS) -o $#
foo will be built with the default CFLAGS containing -Werror, but bar will be built without.
This is a general-purpose solution that works for all arguments to all programs, rather than requiring each program to supply a --no-foo for every --foo option.
Because it can’t be done from Make command-line, it doesn’t directly answer the question you linked to. But overriding Make variables from the command-line to force stuff to build is a pretty good way to make your unbuildable code even less maintainable!
Simpler way
It looks like you can invoke
gcc -c ... -Werror ... -Wno-error ...
without having GCC complain (GCC 4.7.1). So, you can add -Wno-error to the CFLAGS set up elsewhere in the one makefile where you need it. If you're using GNU make, in the one makefile, you can add:
CFLAGS += -Wno-error
possibly for just the single target that needs it.
Harder way
Otherwise, you need a system for building CFLAGS from components. What I have in the makefile I use for testing answers to questions on SO is:
WFLAG1 = -Wall
WFLAG2 = -Wextra
WFLAG3 = -Wmissing-prototypes
WFLAG4 = -Wstrict-prototypes
WFLAG5 = -Wold-style-definition
WFLAG6 =
WFLAGS = ${WFLAG1} ${WFLAG2} ${WFLAG3} ${WFLAG4} ${WFLAG5} ${WFLAG6}
SFLAGS = -std=c99
GFLAGS = -g
OFLAGS = -O3
UFLAGS =
IFLAG1 = -I${HOME}/inc
IFLAGS = # ${IFLAG1}
CFLAGS = ${OFLAGS} ${GFLAGS} ${IFLAGS} ${SFLAGS} ${WFLAGS} ${UFLAGS}
The main point is that each flag is independently adjustable; I can control the warning flags by setting any of ${WFLAG1} to ${WFLAG6}, or by setting ${WFLAGS} wholesale on the command line, or (indeed) by setting ${CFLAGS}. But because each is individually adjustable, and can tune the warnings relatively easily (the main hassle being determining which WFLAGn needs clobbering).
The UFLAGS is 'user flags' and is only set on the command line; I can add more flags to my command line by setting it.
This way is 'harder' because it requires you to modify the central part of your makefile system where you set CFLAGS. It is also less likely to be understood by your colleagues at first sight.
You can see an example of variable overriding in Git Makefile with CFLAGS which now can be tweaked when invoking Make while using DEVELOPER=YesPlease, with Git 2.22 (Q2 2019)
DEVELOPER (in Git Makefile) is a variable to group more compiler warning.
See commit 6d5d4b4, commit 71a7894, commit 8fb2a23, commit 65260a4, commit 9559f8f, commit 4f14a8c (22 Feb 2019) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit 3cef676, 20 Mar 2019)
Makefile: allow for combining DEVELOPER=1 and CFLAGS="..."
Ever since the DEVELOPER=1 facility introduced there's been no way to have custom CFLAGS (e.g. CFLAGS="-O0 -g -ggdb3") while still benefiting from the set of warnings and assertions DEVELOPER=1 enables.
This is because the semantics of variables in the Makefile are such
that the user setting CFLAGS overrides anything we set, including what
we're doing in config.mak.dev.
So let's introduce a "DEVELOPER_CFLAGS" variable in config.mak.dev and
add it to ALL_CFLAGS. Before this the ALL_CFLAGS variable
would (basically, there's some nuance we won't go into) be set to:
$(CPPFLAGS) [$(CFLAGS) *or* $(CFLAGS) in config.mak.dev] $(BASIC_CFLAGS) $(EXTRA_CPPFLAGS)
But will now be:
$(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS) $(BASIC_CFLAGS) $(EXTRA_CPPFLAGS)
The reason for putting DEVELOPER_CFLAGS first is to allow for
selectively overriding something DEVELOPER=1 brings in.
On both GCC and Clang later settings override earlier ones.
E.g. "-Wextra -Wno-extra" will enable no "extra" warnings, but not if those two
arguments are reversed.
Examples of things that weren't possible before, but are now:
# Use -O0 instead of -O2 for less painful debuggng
DEVELOPER=1 CFLAGS="-O0 -g"
# DEVELOPER=1 plus -Wextra, but disable some of the warnings
DEVELOPER=1 DEVOPTS="no-error extra-all" CFLAGS="-O0 -g -Wno-unused-parameter"
The reason for the patches leading up to this one re-arranged the
various *FLAGS assignments and includes is just for readability.
The Makefile supports assignments out of order, e.g.:
$ cat Makefile
X = $(A) $(B) $(C)
A = A
B = B
include c.mak
all:
#echo $(X)
$ cat c.mak
C=C
$ make
A B C

Good way to do a "switch" in a Makefile

I'm experimenting with an updated build system at work; currently, I'm trying to find a good way to set compiler & flags depending on the target platform.
What I would like to do is something like
switch $(PLATFORM)_$(BUILD_TYPE)
case "Linux_x86_release"
CFLAGS = -O3
case "Linux_x86_debug"
CFLAGS = -O0 -g
case "ARM_release"
CC = armcc
AR = armlink
CFLAGS = -O2 -fx
...
which is not supported by GNU Make. Now, my first thought was to just do
-include $(PLATFORM)_$(BUILD_TYPE)
which is a pretty decent solution, however, it makes it hard to get an overview of what differs between files, not to mention that I'm looking forward to writing & maintaining a good 60-80 files, each containing a set of variable definitions.
Does anyone happen to know a better way to accomplish this? I.e. setting a set of flags and other options based on another variable?
How about:
CFLAGS_Linux_x86_release = -O3
CFLAGS_Linux_x86_debug = -O0 -g
CFLAGS = ${CFLAGS_${PLATFORM}_${BUILD}}
Configuring such parameters would be the task of a configure script.
That being said, you can look into the syntax for conditionals and conditional functions. For example, you could try the following:
ifeq ($(PLATFORM)_$(BUILD_TYPE),Linux_x86_release)
CFLAGS = -O3
endif
ifeq ($(PLATFORM)_$(BUILD_TYPE),Linux_x86_debug)
CFLAGS = -O0 -g
endif
The Makefile used by git is a good example of a Makefile which does non-trivial configuration tasks in the Makefile itself (such as switching on the host type). It's actually quite readable and reasonably simple to use.
Switching to a system which does it for you (automake/autoconf) may be simpler...

Resources