Automake: AM_CFLAGS has no effect - unix

I am trying to add some compilation options in Automake, but none of the approaches work.
Here is my configure.ac:
AC_INIT(...)
AC_PREREQ([2.59])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.10 foreign -Wall no-define])
AC_PROG_CXX
AC_PROG_LIBTOOL
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile src/Makefile test/Makefile])
AC_LANG(C++)
AC_OUTPUT
And I have the parent Makefile.am (in top-level dir):
#AM_CFLAGS = ... # doesn't work
AUTOMAKE_OPTIONS = subdir-objects
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
SUBDIRS = src test
dist_noinst_SCRIPTS = autogen.sh
and a Makefile.am for each source dir; src/Makefile:
include_HEADERS = ...
lib_LIBRARIES = ...
and test/Makefile:
#AM_CFLAGS = ... # doesn't work
bin_PROGRAMS = myprog #test
myprog_SOURCES = ...
myprog_LDADD = ../src/libmylib.a
#myprog_CFLAGS = ... # Doesn't work either
I tried uncommenting all combinations of commented lines, i.e.:
add AM_CFLAGS = ... to the parent Makefile.am - this should set the CFLAGS for all affected sources
add AM_CFLAGS = ... to other two Makefile.ams
add myprog_CFLAGS = ... to Makefile.am (this should set CFLAGS when compiling myprog)
but none of these has any effects. Both my program (myprog) and its library (mylib) are kept being compiled / linked with some default flags which are something like -DHAVE_CONFIG -g -O2.
I also tried using INCLUDES instead of AM_CFLAGS, but didn't help.
Anybody has some idea what is going on here and how to fix it?

It looks like you're compiling C++, in which case the variable to use is AM_CXXFLAGS.
Setting AM_CXXFLAGS should be in the Makefile.am that declares things you're actually compiling (i.e., bin_PROGRAMS, lib_LTLIBRARIES, ...).
If you're repeating yourself, don't forget automake supports an include statement.
Recursive make considered harmful. Modern automake supports subdir-objects. If one Makefile.am gets out of hand, use include statements.
The modern way to turn on libtool is LT_INIT, not AC_PROG_LIBTOOL.
AC_LANG(C++) doesn't do anything at point of configure.ac. It sets the language to use when running configure tests. Besides, AC_LANG_PUSH and AC_LANG_POP are smarter ways of doing that.
Why are you assigning to ACLOCAL_AMFLAGS like that?

I tried adding AM_CFLAGS to the parent Makefile.am as suggested, which didn't work. When I added it to the relevant Makefile.am, it ended introducing two conflicting -g options as shown below:
libtool: link: gcc -std=gnu99 -g -O0 -g -O2 -Wl -pthread ...
The correct way to disable optimization is to add CFLAGS = -g -O0 to the Makefile.am where it's needed. Try deleting Makefile.in and Makefile (no extension) if the change doesn't take effect for some reason.
Here's the correct linker directive:
libtool: link: gcc -std=gnu99 -g -O0 -Wl -pthread ...

Related

Rcpp sourceCpp compiler settings

I am using Rcpp to speed up a function that gets called repeatedly in R (3.4, Windows7) and I was hoping to change the compiler settings.
When I call:
sourceCpp("scoreseq1.1.cc", verbose=TRUE)
Part of the output reads:
C:/RBuildTools/3.4/mingw_64/bin/g++ -I"C:/PROGRA~1/R/R-34~1.1/include" -O2 -Wall -mtune=core2 -c scoreseq1.1.cc -o scoreseq1.1.o
I would like to change -mtune to haswell, and -O2 to -O3 in search of some performance improvements.
Is there a way to do that through the sourceCpp or cppFunction, do I need a special header in my.cc file, or do I need to I need to modify some file on my system (and if so, what file?!)
Thanks!
No, you can't (easily), and in general not from a function.
These settings are "fixed" from when R itself is built. You can edit the file -- but you will have to so each time R is rebuilt / reinstalled.
On my box the file is $(R RHOME)/etc/Makeconf.
Just in case someone has a similar problem. You can do this in your C++ source. The following overrides command-line compiler settings:
void
__attribute__((optimize("-O3"),target("tune=haswell")))
foo()
{
// your code goes here
}
For reference take a look at: https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html.

No rule to make target in Maefile

I'm learning to write makefiles. I made my own simple one just to try and test, but every time I run make, i get:
make: *** No rule to make target `/%.cpp', needed by `obj'. Stop.
I googled. I'm pretty sure I typed everything correctly, and my folders are set up the way they should be. Here is the makefile:
CC = g++
LD = g++
NAME = app
OBJ_DIR = obj
SRC_DIR = src
CC_FLAGS = -std=c++0x
all: $(NAME)
$(NAME): $(OBJ_DIR)/%.o
$(LD) $(OBJ_DIR)/%.o -o $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CC) $< -o $# $(CC_FLAGS)
clean:
rm $(NAME) $(OBJ_DIR) -rf
What is the problem?
The line:
$(NAME): $(OBJ_DIR)/%.o
is not correct. This is not a pattern rule (because the target doesn't contain a pattern character, %) and so it's interpreted as an explicit rule, saying that app depends on the actual file named obj/%.o which doesn't exist, and make doesn't know how to build it (because there's no file src/%.cpp).
You need to change this to:
$(NAME): $(OBJ_DIR)/foo.o ...
or whatever object files you have.

makefile rule to build multiple targets without intermediate file

I am stumped coming up with a makefile rule to have several executables where each depends on its respective source file. There is a library common to all and each program has a single source file: a.c compiled and linked with the library produces executable a, etc.
LIB_C_FILES = f1.c f2.c f3.c
LIB_H_FILES = f1.h f2.h f3.h
TARGETS = a b c
CFLAGS = -g -O0 -DDEBUG
.PHONY : all clean
.c.o:
g++ -c $(CFLAGS) -o $# $<
all: $(TARGETS)
${TARGETS} : lib.a ${#:%=%.c}
g++ $(CFLAGS) ${#:=.c} -o $# lib.a
lib.a: ${LIB_C_FILES:.c=.o} $(LIB_H_FILES)
ar r $# $?
The library portion works fine. And when an executable does not exist, it also works fine. But when one of the standalone source files is modified it says make: Nothing to be done for 'all'.
I don't understand the proper way to make target a depend on source a.c individually in a list. What am I missing?
Just for completeness: you can do what you want with plain old static pattern rules, so long as you can match all of ${TARGETS} with make's (noddy) pattern matching.
${TARGETS}: %: %.C lib.a
g++ ${CFLAGS} $< -o $# lib.a
lib.a: ...
ar ...
A tad more readable, and perhaps more compatible than .SECONDEXPANSION?
First, I assume fio.a was a typo (you probably meant lib.a).
Second, I think the tricky part is your ${#:%=%.c} prerequisite. AFAIK, $# can't be used this way.
I think you can get the behavior you're looking for using .SECONDEXPANSION though.
Try:
.SECONDEXPANSION:
${TARGETS} : lib.a $$(patsubst %,%.c,$$#)
There may be an old-style substitution way to do this, but I find the patsubst line to be more readable than ${#:%=%.c}.
(I should add that this applies to Gnu make 3.82. YMMV with older versions of Gnu make, or [heaven forbid] non-Gnu versions of make).

makefiles implicit and explicit rule

I have a rule
*.o: *.c
gcc <certain compiler switches>
I would like to build a few *.c files with different compiler switches than the standard rule.
I believe I simply add before the first rule
foo.o : foo.c
foobar.o : foobar.c
gcc <other compiler switches>
Does the explicit rule of foo and foobar override the *.o : *.c rule?
There are lots of problems with your makefile. *.o: *.c uses shell wildcards and is almost certainly not what you want. You are probably wanting to write a pattern rules using make wildcards—%.o: %.c. I don't like these much (pattern rules that is). I always like to be very explicit in my makefiles. Something like:
SRCS := foo.c foobar.c
OBJS := ${SRCS:%.c=%.o}
${OBJS}: %.o: %.c
gcc ${OPTS-${#D}} $< -o $#
Now you can define OPTS-foo and OPTS-foobar as you see fit.

Running make from Outside the Tree

Let's say I have a makefile like the following:
CXXFLAGS := -I./Include
Foo:
$(CXX) $(CXXFLAGS) -o Foo
If the user cds into the source tree and runs make, everything is fine and dandy. However, if make is invoked from somewhere outside the source tree, the include directory will be incorrect.
Using full paths instead of relative paths works, but that destroys the portability of the makefile.
Should I just rely on users invoking make "properly?" Or is there an easy way to get around this?
If you want to have CXXFLAGS be -Isome_dir/Include
when the make is invoked asmake -f some_dir/Makefile,
MAKEFILE_LIST
might meet the purpose.
For example:
MAKEFILE_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
CXXFLAGS := -I$(MAKEFILE_DIR)Include
If your make's version is 3.80 or lower, lastword might not work.
In that case,
$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) will work instead.
EDIT: This answer is for GNU-make.
Use the -C flag.
make -C my_dir
You could present your users a compile command that looks like (cd /to/proper/directory && make -k)

Resources