Prevent variable overwrite into submakefile - linux

I have a makefile compiling a shared library which I call from another makefile.
When developping the library I used the variable TARGET to name the library binary.
BUILD_DIR?=$(abspath ./build)
SRC=src/file.c
INC=-I inc
CFLAGS+=-Wall -Werror
LDFLAGS+=-Wl,--no-undefined
TARGET=libname
ifndef ARCH
$(error Undefined ARCH (Library targetted architecture))
endif
default: all
all: ${BUILD_DIR}/${ARCH}/${TARGET}
${BUILD_DIR}/${ARCH}/${TARGET}: ${BUILD_DIR}/${ARCH}
${CC} ${CFLAGS} ${LDFLAGS} -fPIC -shared -o $#.so ${SRC} ${INC}
${BUILD_DIR}/${ARCH}:
#mkdir -p $#
clean:
#rm -rf ${BUILD_DIR}/${ARCH}/${TARGET}
.PHONY: all clean ${BUILD_DIR}/${ARCH}/${TARGET} ${BUILD_DIR}/${ARCH}
However, into the parent makefile, I use the variable TARGET to specify the board on which I'm deploying the app.
ifeq (${TARGET},target1)
# Target1 compiling
${LIB}:
scp $# ${TARGET_USR}#${TARGET_IP}:
${SSH_CMD} make -C $# ARCH=arm
[...]
endif
ifeq (${TARGET},target2)
# Target2 compiling
${LIB}:
make -C $# BUILD_DIR=${BUILD_DIR} CC=${CC} ARCH=${ARCH}
[...]
endif
I'm compiling as follow: make TARGET=target2 and I'm using GNU make
Compiling the library from the parent makefile succeed but the name of the library is target2.so instead of libname.so.
I thought variables were passed to submakefiles only if explicitly precised on the command call (as for BUILD_DIR, CC and ARCH) but it seems that TARGET is also passed to sub makefile.
I know that I could just do override TARGET=libname into the sub makefile.
But I would like to know if there is another solution.

By default, any command line variable arguments will override any local assignments in the makefiles. There is a way around this by using the override directive:
override TARGET := libname
This will set the variable in the child makefile, regardless of whether the value was specified on the command line.

Related

adding additional sources directory to c makefile

sorry if this is noob question.
In my c function, I use a macro defined in btrfs_inode.h file.
When I include the file directly to path:
#include "/data/kernel/linux-4.1.21-x86_64/fs/btrfs/btrfs_inode.h"
the project compiles with no errors, I dont want to use that direct path, I download the package kernel-source that contains this header file.
The location of the header file after installing the package is at: /usr/src/linux/fs/btrfs/
So I change the #include to :
#include "btrfs_inode.h"
and i wish to add "/usr/src/linux/fs/btrfs/" as a location that it will search for "btrfs_inode.h" and get: "/usr/src/linux/fs/btrfs/btrfs_inode.h"
I get error:
/bin/sh: 1: /usr/src/linux/fs/btrfs/: Permission denied
I am running make as root.
Makefile:
all:: user
obj-m += my-driver.o
# Make arguments
PWD := $(shell pwd)
INCLUDE := -I/usr/include/asm/mach-default/
KDIR := /lib/modules/$(KERNEL_HEADERS)/build;/usr/src/linux/fs/btrfs/
# Add flags to auto build
EXTRA_CFLAGS +=-D__Linux -std=gnu99
# extra warning flags
ccflags-y := -Wall -Wextra #-pedantic
# disable some warning flags
ccflags-y += -Wno-unused-parameter
# make all warnings into errors
ccflags-y += -Werror
# increase verbosity
KBUILD_VERBOSE := 1
all::
$(MAKE) -C $(KDIR) $(INCLUDE) SUBDIRS=$(PWD) modules
So first off, avoid making as root when possible. Next, you added your directory to KDIR, not to INCLUDE (and then you pass KDIR to the -C argument of make, so you would have a line that looks like:
make -C /lib/modules/$(KERNEL_HEADERS)/build;/usr/src/linux/fs/btrfs/ ...
Notice the semicolon, which bash will interperet as the end of a command, and beginning of the next command. So it tries to run make, and then tries to run /usr/src/linux/fs/btrfs/, and gives you your warning. What you should have is something like:
# Make arguments
PWD := $(shell pwd)
INCLUDE := -I/usr/include/asm/mach-default/
INCLUDE += -I/usr/src/linux/fs/btrfs/
KDIR := /lib/modules/$(KERNEL_HEADERS)/build
(you want a -I in front of the path to tell make to search for include files in that directory).
EDIT
You are also not passing the -I to your $(CC) or $(CXX) commands. To do this, you have a couple of options, though I'll suggest the least error prone one: First of all, you have to pass the flags to the sub make. To do this, first add the line:
export INCLUDE
to your main makefile. Your submake now has access to the variable $(INCLUDE). From there, if you have an explicit rule to compile the CC files, you can add $(INCLUDE) to the compile command. Something like
%.o: %.c
$(CC) $(CFLAGS) $(INCLUDE) -o $# $<
or, if you are using the built-in implicit rules, simply add $(INCLUDE) to CPP_FLAGS:
CPP_FLAGS += $(INCLUDE)
(note, CPP_FLAGS are used by default for both c and c++ compilation).
Finally, do not pass $(INCLUDE) to your make command. If you do, it tells make to look look for sub-makefiles in those directories (not gcc...).
From what I could understand via this question, you can add multiple -I flags to your Makefile.

how to set a compiler flag by enabling a feature in autoconf

I am very new to Autoconf, I would like to have a configure file that when I call: configure --enable-gtest=yes, such that it adds a compiler flag. The following code that I put up after searching looks as follow, but does not do the trick.
Thanks a lot
this is how my makefile looks like.
-include Makefile.config
SRC = $(wildcard *.cpp)
OBJ = $(SRC:.cpp=.o)
install: $(OBJ)
$(CC) $(CXXFLAGS) $(DEBUGFLAG) $(OBJ) -o run
%.o:%.cpp
$(CC) $(CXXFLAGS) $(DEBUGFLAG) -c $<
clean:
rm -f *.o
this is my configure.ac
AC_INIT([test], [1.7.0])
AC_PREREQ([2.59])
AC_CONFIG_MACRO_DIR([m4])
AC_CHECK_PROGS(CXX, [g++ c++ clang], ":")
AC_PROG_CXX
AC_SUBST(CXX)
AC_ARG_ENABLE([debug],
[ --enable-debug Turn on debugging],
[case "${enableval}" in
yes) debug=true ;;
no) debug=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
esac],[debug=false])
AM_CONDITIONAL([DEBUG], [test x$debug = xtrue])
AC_CONFIG_FILES(Makefile.config)
AC_OUTPUT
and my
Makefile.config.in
CC = #CXX#
CXXFLAGS = -std=c++14
if DEBUG
DBG = debug
else
DBG =
endif
thanks
Pretty close! But not quite.
You're probably best off using Automake, which automates a lot of the Makefile drudgery for you. But if you really want to avoid it, then you have to write your Makefile correctly according to what you write in configure.ac.
AM_CONDITIONAL([DEBUG], [test x$debug = xtrue])
This defines a couple of autoconf substitutions, like DEBUG_TRUE and DEBUG_FALSE. The if form you've chosen only works in Automake, in an ordinary Makefile you have to write something like:
#DEBUG_TRUE#...stuff when
#DEBUG_TRUE#...true
Alternatively you can test the values of the substitutions using GNU make's if statement.
Another approach is not to use AM_CONDITIONAL at all but rather AC_SUBST the thing you want to use in your Makefile.config.in.

The effect of the following Makefile lines is?

Can somebody explain the effect of the following MACRO command please?
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
When make is called with the target that equals what is contained in the variable $(EXECUTABLE) (only you can say what that might be), then execute the c compiler with the defined linker flags and compile the objects into the outfile which is named like the target.
So a call to make myprog would result in the c compiler creating the executable myprog.

Converting a visual studio makefile to a linux makefile

i am new to makefiles and have just rescently created a makefile that works for a c++ project. it has two cpp files and one h file. i am trying to convert my file to work in linux but cant seem to figure out how. any ideas?
EXE = NumberGuessingGame.exe
CC = cl
LD = cl
OBJ = game.obj userInterface.obj
STD_HEADERS = header.h
CFLAGS = /c
LDFLAGS = /Fe
$(EXE): $(OBJ)
$(LD) $(OBJ) $(LDFLAGS)$(EXE)
game.obj: game.cpp $(STD_HEADERS)
$(CC) game.cpp $(CFLAGS)
userInterface.obj: userInterface.cpp $(STD_HEADERS)
$(CC) userInterface.cpp $(CFLAGS)
#prepare for complete rebuild
clean:
del /q *.obj
del /q *.exe
For in depth treatment of make on Linux, see GNU make.
There are a few differences. Binaries have no extension
EXE = NumberGuessingGame
The compiler is gcc, but need not be named, because CC is built in, same goes for LD. But since your files are named .cpp, the appropriate compiler is g++, which is CXX in make.
Object files have extension .o
OBJ = game.o userInterface.o
STD_HEADERS = header.h
Compiler flags
CXXFLAGS = -c
The equivalent for /Fe is just -o, which is not specified as LDFLAGS, but spelled out on the linker command line.
Usually, you use the compiler for linking
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $(OBJ) -o $(EXE)
You don't need to specify the rules for object creation, they are built in. Just specify the dependencies
game.o: $(STD_HEADERS)
userInterface.o: $(STD_HEADERS)
del is called rm
clean:
rm -f $(OBJ)
rm -f $(EXE)
One important point is, indentation is one tab character, no spaces. If you have spaces instead, make will complain about
*** missing separator. Stop.
or some other strange error.
You can also use CMake to accomplish your task:
Put following into CMakeLists.txt file in the root directory of your project (<project-dir>):
cmake_minimum_required (VERSION 2.6)
project (NumberGuessingGame)
add_executable(NumberGuessingGame game.cpp serInterface.cpp)
Then on the console do
"in-source" build
$ cd <project-dir>
$ cmake .
$ make
or "out-source" build
$ mkdir <build-dir>
$ cd <build-dir>
$ cmake <project-dir>
$ make
You can adjust build setting using nice GUI tool. Just go to the build directory and run cmake-gui.
You don't need to include headers in the dependency list. The compiler will fail on its own, stopping make from continuing. However, if you're including them in the dependency list to force make to rebuild files in case the header changes, nobody will stop you.
CFLAGS never needs to contain -c, nor does LDFLAGS need -o. Below is a revamped makefile. Note that you can always override a macro explicitly defined in a makefile or implicitly defined using something like make CFLAGS=-Wall for example. I used the de facto standard CXX macro name in the event that you have C source files, which must be compiled using a C compiler (the value of the CC macro) instead of a C++ compiler.
.POSIX:
#CC is already implicitly defined.
CXX = g++
OBJ = game.o userInterface.o
STD_HEADERS = header.h
.SUFFIXES:
.SUFFIXES: .o .cpp .c
NumberGuessingGame: $(OBJ) $(STD_HEADERS)
$(CXX) $(CFLAGS) -o $# $(OBJ) $(LDFLAGS)
.cpp.o: $(STD_HEADERS)
$(CXX) $(CFLAGS) -c $<
#There is already an implicit .c.o rule, thus there is no need for it here.
#prepare for complete rebuild
clean:
-rm -f NumberGuessingGame *.o
As yegorich answered, you can use a build system like Cmake. It is much more flexible, cross-platform, and can generate Unix Makefiles as well as Nmake Makefiles and Visual Studio solutions on Windows.

Easy makefiles for gcc/g++

My projects almst always consist of:
Pairs of Foo.h and Foo.cpp
Some extra headers util.h etc.
What is the simplest way to write a makefile that
Runs
$CC -c foo.cpp
for each .cpp file, keeping a dependency to its coresponding .h file
Provides some way that I can manually add extra dependencies
Includes a linking step with my manuall set $LIBS variable.
I work with Linux(Ubuntu) and gcc/g++.
Please, just use automake. You'll get proper dependency tracking, makefiles that comply with the GNU Makefile Standards (e.g., make install does the correct thing and respects DESTDIR and prefix), the ability to check for system quirks as needed and support for building proper distribution tarballs.
This is a minimal configure.ac:
-*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.61])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AM_INIT_AUTOMAKE([foreign])
# Checks for programs.
AC_PROG_CXX
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
and a minimal Makefile.am:
## Process this file with automake to generate Makefile.in
bin_PROGRAMS = foo
foo_SOURCES = foo.cpp bar.h baz.h quux.cpp
Run autoreconf -i to generate the configure script, followed by ./configure and make.
Here is an excellent autotools tutorial.
How about this:
%.o: %.cpp %.h
$(CC) -c $< -o $#
# Some things have extra dependencies. (Headers like util.h are unlikely
# to change, but you can handle them this way if you really want to.)
#
# foo.o and bar.o both depend on baz.h
foo.o bar.o: baz.h
# foo.o also depends on gab.h and jig.h
foo.o: gab.h jig.h
# You will need a list of object files. You can build it by hand:
OBJ_FILES = foo.o bar.o snaz.o # and so on
# ...or just grab all the files in the source directory:
SOURCE_FILES = $(wildcard *.cpp)
OBJ_FILES = $(SOURCE_FILES:.cpp=.o)
# It is possible to get this from the environment, but not advisable.
LIBS = -lred -lblue
final-thing: $(OBJ_FILES)
$(CC) $(LIBS) $^ -o $#
Perhaps you can check out CMake?
If you're unfamiliar with CMake, it's basically a Makefile generator (or XCode, or Visual Studio Projects, etc, depending on platform), so it lets you specify just the variables you need, and takes care of header dependency issues for you, makefile generation, etc.
Here is a simple shell script that constructs a makefile from all .cpp files in a given directory:
# !sh
if [ $# = 0 ]
then
echo -e "please give executable name"
exit 1
fi
echo -e -n "CC=g++\nOPTIMS=\nLIBS= " > makefile
echo >> makefile
echo -n "$1: " >> makefile
for fic in *.cpp
do
echo -n "${fic%\.cpp}.o " >> makefile
done
echo >> makefile
echo -n -e "\t\$(CC) " >> makefile
for fic in *.cpp
do
echo -n "${fic%\.cpp}.o " >> makefile
done
echo -n -e "-o $1 \$(OPTIMS) \$(LIBS)\n" >> makefile
echo >> makefile
for fic in *.cpp
do
g++ -MM $fic >> makefile
echo -e "\t\$(CC) -c $fic \$(OPTIMS)\n" >> makefile
done
exit 0
It uses the -MM option of gcc for creating makefile dependency lines. Just create the script in the sources directory, (let's call it micmake), make it executable (chmod +x micmake) and type
./micmake go
It will create a makefile and the make command compile your project. The executable is named go. You can edit the makefile if you need special compilation options or libraries. For more complex projects and dependencies, you should use automake, cmake or scons.
start here simple makefile for gcc
Here is an example from one of my projects -- you can simply drop new pairs foo1.cc and foo1.h in there and they will automagically be built for you:
# determine all sources and from that all targets
sources := $(wildcard *.cpp)
programs := $(sources:.cpp=)
## compiler etc settings used in default make rules
CXX := g++
CPPFLAGS := -Wall
CXXFLAGS := -O3 -pipe
LDLIBS :=
# build all and strip programs afterwards
all: $(programs)
#test -x /usr/bin/strip && strip $^

Resources