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.
Related
I'm trying to understand the following line in a Makefile.in file:
CXXFLAGS += -O3 -DNDEBUG -std=c++11 -Wno-deprecated-declarations -Isrc -I #mathinc#
I know the -I flag adds a directory to the list of places where the compiler will search for included files but what does #mathinc# mean?
Note that the file is called Makefile.in -- this signifies that it is input to another file (or transformation).
In short, configure will run and determine, say, where the relevant include files are for #mathinc -- likely some math headers. After you run configure it will produce Makefile (no trailing .in) based on what it finds. Do inspect that file.
configure scripts are created in a system called autoconf which, like all build systems, has its fans and its haters. There are some decent tutorials as for example this one.
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.
As we know, in the appliance when we use the command
make [file-name]
It automatically compiles with some flags:
-ggdb -O0 -std=c99 -Wall - Werror
I need to know in which directory the CS50 edited Makefile is located, because I want to configure my own Makefile for the entire system by which I can make any .cpp file.
When I compile c++ file with make it automatically compiles with g++ but I want to compile .cpp file with clang++ compiler, adding some essential flag such for -g for debugging -O0 for assembly code.
I'm asking how to create a Makefile for that specific reasons, if possible.
Make uses Makefiles in the current directory and Implicit-Rules. You can modify the behavior of implicit rules by changing the variables that those explicit rules use.
For example, to change the compiler for .cpp files, you could set your own CXX variable, either
in the environment (Make uses it):
CXX=clang++ make [file-name]
#OR
export CXX=clang++; make [file-name]
in a local Makefile:
CXX:=clang++
#The implicit rule, which you'll find in the link, takes care of the rest
I just recently switched back to Linux from windows and VC, but I never done any special coding using g++ compiler.
Currently my libraries (boost and others) are scattered all over the hard drive and I need to learn how to setup my compiler and linker so that all the compiler settings..
(includes, libs, flags) etc.. will be held in one single file or place, so that it becomes easy to manage, because I don't want to type these things every time I launch the compiler on command line.
Also note that I'm using a vim as my code editor and do not want to use IDE.
What is the best way to achieve that goal?
You need to use some of Building tools. It's allow you type small command (in vim you need just type :make) which launch build process with predetermined parameters (includes, libs, etc).
For C++ in Linux the most common tools are:
- make;
- automake;
- CMake.
If you use Qt also qmake is available.
I've had experience with all of them and my suggestion is use plain make for small projects and CMake for others and don't use autotools while you don't have to do it.
Note: All hight-level tools just help generate appropriate files (Makefile) for plain make (CMake generate Makefile based on CMakeLists.txt, automake based on Makefile.am, qmake based on *.pro).
because I don't want to type these things every time I launch the
compiler on command line.
I don't like to type either. All I want to do for small builds is issue:
(1) a short alias (2) the name of the file to compile, and (3) an output file.
Then I want my tool to take care of all common options, and if necessary, include the paths to any extra -I include directories, -L library directories and form the command line for me.
I have a short script that can handle the drudgery. Separating your projects into separate directories and including a 'bldflags' file with specific options allows the scripts to load any project specific options you may require. It is flexible enough to take any additional options specified on the command line. Alias the script in your .bashrc, and all that is required for quick builds is:
g+ filename.cpp outname
Now this is a very basic script and is not intented to replace proper build tools for your projects, but for quick compilations, it, or something like it, will sure cut down on the typing required. Here is the short script:
#!/bin/bash
## validate input
test -n "$1" && test -n "$2"|| { echo "insufficient input. usage: ${0//*\//} source.cpp out [options]"; exit 1; }
## set standard build flags and test if exists/source ./bldflags
stdclfags="-Wall" # add any standard flags you use.
test -r ./bldflags && bldflags="`<./bldflags`"
## show build command and call g++
echo -e "building $1 with:\n g++ $stdclfags -o $2 $1 $bldflags ${#:3}"
g++ $stdclfags -o "$2" "$1" $bldflags ${#:3}
exit 0
Make the script executable and include a simple alias in your .bashrc giving it any name you like:
alias g+='/home/david/scr/utl/bgc++.sh'
Examples of basic use: (basic without additional flags or a ./bldflags file)
$ g+ input.cpp output
building input.cpp with:
g++ -Wall -o output input.cpp
With a few extra options added on the command line:
$ g+ input.cpp output -Wunused -fno-default-inline
building input.cpp with:
g++ -Wall -o output input.cpp -Wunused -fno-default-inline
Including project specific options in ./bldflags (e.g: -I/home/david/inc -L/home/david/lib -Wl,-rpath=/home/david/lib
g+ input.cpp output -Wunused -fno-default-inline
building input.cpp with:
g++ -Wall -o output input.cpp -I/home/david/inc -L/home/david/lib -Wl,-rpath=/home/david/lib -Wunused -fno-default-inline
So to address the I don't want to type these things every time I launch the
compiler on command line, this is a very quick and easy way I've found to cut the typing down to a minimum for quick/repetitive builds where a full Makefile isn't needed.
How can I make GNU Make use a different compiler without manually editing the makefile?
You should be able to do something like this:
make CC=my_compiler
This is assuming whoever wrote the Makefile used the variable CC.
You can set the environment variables CC and CXX, which are used for compiling C and C++ files respectively. By default they use the values cc and g++
If the makefile is written like most makefiles, then it uses $(CC) when it wishes to invoke the C compiler. That's what the built-in rules do, anyway. If you specify a different value for that variable, then Make will use that instead. You can provide a new value on the command line:
make CC=/usr/bin/special-cc
You can also specify that when you run configure:
./configure CC=/usr/bin/special-cc
The configuration script will incorporate the new CC value into the makefile that it generates, so you don't need to manually edit it, and you can just run make by itself thereafter (instead of giving the custom CC value on the command line every time).
Many makefiles use 'CC' to define the compiler. If yours does, you can override that variable with
make CC='/usr/bin/gcc'
Use variables for the compiler program name.
Either pass the new definition to the make utility or set them in the environment before building.
See Using Variables in Make
Makefile:
#!MAKE
suf=$(suffix $(src))
ifeq ($(suf), .c)
cc=gcc
else
ifeq ($(suf), .cpp)
cc=g++
endif
endif
all:
$(cc) $(src) -o $(src:$(suf)=.exe)
clean:
rm *.exe
.PHONY: all clean
Terminal:
$ make src=main.c