What does the "#" symbol mean in a makefile when after an -I flag such as -I #mathinc#? - c++

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.

Related

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.

--with-sysroot is not honored during a compile on OS X?

I have a C++ project. I am testing a cross-compile with Autotools on OS X for iOS. I configure with:
$ echo $IOS_SYSROOT
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.2.sdk
$ CXXFLAGS="-DNDEBUG -g2 -O3 -arch arm64" ./configure --with-sysroot="$IOS_SYSROOT" --build=`config.guess` --host=aarch64-ios
When make'ing it results in (line breaks added for clarity):
libtool: compile: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
-DHAVE_CONFIG_H -I. ... -DNDEBUG -g2 -O3 -arch arm64 -MT adhoc.lo -MD -MP -MF .deps/adhoc.Tpo -c adhoc.cpp -o adhoc.o
In file included from adhoc.cpp:2:
In file included from /usr/include/c++/4.2.1/iosfwd:44:
In file included from /usr/include/c++/4.2.1/bits/c++config.h:41:
In file included from /usr/include/c++/4.2.1/bits/os_defines.h:61:
In file included from /usr/include/unistd.h:71:
In file included from /usr/include/_types.h:27:
In file included from /usr/include/sys/_types.h:32:
/usr/include/sys/cdefs.h:658:2: error: Unsupported architecture
#error Unsupported architecture
...
Notice the wrong header files are being used. The build system's headers are used rather than the iPhone headers. I'm fairly certain --with-sysroot is not being honored. Searching for the keywords seems to indicate its a widespread problem with Autoconf (based on all the bug reports trying to use the feature).
Manually adding CXXFLAGS="-sysroot=$IOS_SYSROOT -arch arm64 ... seems to fix the issue. This seems to be the same problem (or nearly the same problem) detailed at Bug 79885: --with-build-sysroot= does not get honored throughout the build.
There does not seem to be a AC_SYSROOT (or similar) to copy --with-sysroot into AM_CXXFLAGS. Searching the Autoconf site for the keywords is not returning useful hits: "--with-sysroot" site:https://www.gnu.org/software/autoconf/manual.
How are we supposed to handle Autoconf's --with-sysroot option? What is the practice packagers are supposed to follow?
Here are the Autoconf prject files: cryptopp-autotools. There are two files of interest, and they are configure.ac and Makefile.am. I'm not sure what applies to this problem at the moment.
Here's the message where Autoconf tells users to use it:
$ ./configure --help | grep sysroot
--with-sysroot[=DIR] Search for dependent libraries within DIR (or the
compiler's sysroot if not specified).
I'd prefer to supress the message if Autoconf cannot wire-in --with-sysroot properly. Otherwise, users are going to be filling bug reports against us.

Atmega, avr-gcc, assembly include file from another directory

I can't convince avr-gcc on windows to include a *.h file from another directory:
>avr-gcc -Wa,-gdwarf2 -x assembler-with-cpp -c -mmcu=atmega256rfr2 halW1.S
C:\Users\me\AppData\Local\Temp\ccjzoYpN.s: Assembler messages:
C:\Users\me\AppData\Local\Temp\ccjzoYpN.s:6: Error: can't open halGccD.h for reading: No such file or directory
The required file is one up level in ../include folder
(this is the BitCloud stack provided by Atmel itself)
I tried as Atmel Studio does to pass include folder:
>avr-gcc -Wa,-gdwarf2 -x assembler-with-cpp -c -mmcu=atmega256rfr2 halW1.S -I "..\include"
But seems that avr-gcc assembler ignores the -I option. I tried with relative, absolute, even put that path in global PATH.
If I copy required *.h in the same folder where *.S file resides, it's working.
What is wrong?
Ok, found'it by mistake.
In case anyone needs, -I is not working alone for assembly files. When using avr-gcc as assembler, explicit assembler (-Wa) or linker (-Wl) directives must precede others. Such as:
-Wa,-I"..\..\path_to_h"
Also pay attention to backslash (not slash)... the old windows problem.
Seems that avr-gcc should parse correctly, but is not.

g++ compiler option using `pkg-config...` results in -I(directory) What does the -I mean?

I am familiar with very simple g++ commands that compile and link programs, however when working with GTK+ I found the tutorial indicate that I should use pkg-config --cflags gtk+-2.0
Now when I type in pkg-config --cflags gtk+-2.0 to the terminal I get a list of libraries and files like this...
-pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/harfbuzz
So my question is, what does the -I mean in front of a directory? For example -I/usr/include/libpng12
The -I flag is used to add directories to the list of directories to search for finding files in #include <> statements.
In your case, when a file is included by using #include, /usr/include/libpng12 will be one of the directories in which the pre-processor will search for the file.
Please read the manual. All command line options are present there :-)
-I set the search path for libraries.
https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
-I is simply adding to the paths to be searched for header files. Note that these are searched before system paths.
You can find pretty much all the options for gcc/g++ here. In this case, you want the Directory Search options specifically; see here. From that page:
-Idir
Add the directory dir to the head of the list of directories to be
searched for header files. This can be used to override a system
header file, substituting your own version, since these directories
are searched before the system header file directories. However, you
should not use this option to add directories that contain
vendor-supplied system header files (use -isystem for that).
If you use more than one -I option, the directories are scanned in
left-to-right order; the standard system directories come after. If a
standard system include directory, or a directory specified with
-isystem, is also specified with -I, the -I option is ignored. The directory is still searched but as a system directory at its normal
position in the system include chain. This is to ensure that GCC's
procedure to fix buggy system headers and the ordering for the
include_next directive are not inadvertently changed. If you really
need to change the search order for system directories, use the
-nostdinc and/or -isystem options.
As the answers from #R Sahu #Klaus and #Yuushi explain, the -I dir tells the compiler where to look for the #include header.h file.
When the program is compiled, it will be linked. You will probably also need to tell the linker where to find the programs that support the functions in the #included headers. This is done with the -llibrary flag. That is a lower case l not a one (1).
The pkg-config command references a set of files and will supply the compiler flags --cflags and link flags --ldflags if you supply the package name.
Put the returned -Includes before the source name(s) and the -l's after in your compile command request.
For other than casual, one-off programs, you should use make. The cflag and ldflag info can be put in variables in the Makefile and referenced throughout your make script.
You can get a complete list of packages configured to pkg-config on your Ubuntu system with locate *.pc

Setting up g++ compiler and linker options

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.