I have a small fortran program with some pre-processor directives written in a *.F90 file. Now, I would like to generate a *.f90 fortran file from it, which removes all the extra code in the *.F90 file corresponding to the other non-activated directives.
In pgifortran, all I have to do is :
pgf90 -F file_name.F90
And that is it! It produces a *.f90 file having the lines relevant to the active directives.
How can I do this in gfortran?
GNU Fortran options
See https://gcc.gnu.org/onlinedocs/gfortran/Preprocessing-Options.html for full details, but you may observe that the option -E preprocesses foo.F90 to stdout (you can, of course, pipe it to e.g. foo.f90).
The -E option is valid for the GNU compiler front-ends in general, and works for C, C++ and Fortran.
While preprocessing is enabled by default for files with the extentions .fpp, .FPP, .F, .FOR, .FTN, .F90, .F95, .F03 or .F08, you can enable it manually with -cpp. You can also disable it manually with -nocpp.
Example Program
program main
implicit none
#ifdef USER_MACRO
print*,'USER_MACRO was defined'
#endif
#ifdef __GFORTRAN__
print*,'I am GNU Fortran (aka gfortran)!'
#endif
#ifdef __GNUC__
print*,'I am GNU C (or its preprocessor)!'
#endif
end program main
Result from GNU C preprocessor (cpp)
$ cpp -E fpp.F90
# 1 "fpp.F90"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 324 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "fpp.F90" 2
program main
implicit none
print*,'I am GNU C (or its preprocessor)!'
end program main
Result from GNU Fortran
$ gfortran -E fpp.F90
# 1 "fpp.F90"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "fpp.F90"
program main
implicit none
print*,'I am GNU Fortran (aka gfortran)!'
print*,'I am GNU C (or its preprocessor)!'
end program main
Obviously, you can see how user-defined symbols are preprocessed, too:
$ gfortran -E -DUSER_MACRO fpp.F90
# 1 "fpp.F90"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "fpp.F90"
program main
implicit none
print*,'USER_MACRO was defined'
print*,'I am GNU Fortran (aka gfortran)!'
print*,'I am GNU C (or its preprocessor)!'
end program main
Result from Intel Fortran
In case it is of interest, Intel compilers support the same options as GCC:
$ ifort -E -DUSER_MACRO fpp.F90
# 1 "fpp.F90"
program main
implicit none
print*,'USER_MACRO was defined'
# 8
# 11
end program main
Preprocessing with IBM XL Fortran
The IBM XL Fortran man pages have the full details, but it is important to note that preprocessor symbols must be provided via -WF,-DUSER_MACRO instead of -DUSER_MACRO.
Related
I'm working on Solaris with SunCC. Autoconf's AC_COMPILE_IFELSE and AC_LINK_IFELSE are misdetecting compiler features. Autoconf is reporting features are available even though the compiler rejects them with messages such as illegal option.
$ echo 'int main(int argc, char* argv[]) {}' > test.C
$ /opt/solarisstudio12.4/bin/CC test.C
$ /opt/solarisstudio12.4/bin/CC -msse4.2 -msha test.C
CC: Warning: Option -msse4.2 passed to ld, if ld is invoked, ignored otherwise
CC: Warning: Option -msha passed to ld, if ld is invoked, ignored otherwise
ld: fatal: option '-h a' is incompatible with building a dynamic executable
$ /opt/solarisstudio12.4/bin/CC -xarch=sha test.C
CC: Warning: illegal use of -xarch option, illegal value ignored: sha
I'd like to try to workaround the misdetections, but I need to know the compiler to do it. Autoconf has some macros that provide canonicalized names for CPU, Vendor and OS, but they do not appear to include the compiler or its vendor.
How do we detect or determine compiler name or vendor in Autoconf?
Adding the following is not really helpful since it does not identify the compiler.
AC_MSG_NOTICE(["Build: $build"])
AC_MSG_NOTICE(["Compiler: $compiler"])
Then:
CXX=/opt/solarisstudio12.4/bin/CC ./configure
...
configure: "Build: i386-pc-solaris2.11"
configure: "Compiler: /opt/solarisstudio12.4/bin/CC"
I don't think there is a standard way to do this.
We manually check for the existence of compiler macros according to predef.sourceforge.net and perhaps more sources like cc --version, the cc's command name, the operating system name, ...).
I.e. you compile a program, and check for defines.
If it doesn't exist / the programm #errors out -> not SunCC.
It looks messy, but here is an example straight from the Score-P source (vendor/common/build-config/m4/ax_compiler_vendor.m4). Maybe you can take some inspiration from it:
AC_DEFUN([AX_COMPILER_VENDOR],
[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
dnl Please add if possible support to ax_compiler_version.m4
[# note: don't check for gcc first since some other compilers define __GNUC__
vendors="intel: __ICC,__ECC,__INTEL_COMPILER
ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__
pathscale: __PATHCC__,__PATHSCALE__
clang: __clang__
cray: _CRAYC
fujitsu: __FUJITSU
gnu: __GNUC__
sun: __SUNPRO_C,__SUNPRO_CC
hp: __HP_cc,__HP_aCC
dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER
borland: __BORLANDC__,__CODEGEARC__,__TURBOC__
comeau: __COMO__
kai: __KCC
lcc: __LCC__
sgi: __sgi,sgi
microsoft: _MSC_VER
metrowerks: __MWERKS__
watcom: __WATCOMC__
portland: __PGI
tcc: __TINYC__
unknown: UNKNOWN"
for ventest in $vendors; do
case $ventest in
*:) vendor=$ventest; continue ;;
*) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;;
esac
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
#if !($vencpp)
thisisanerror;
#endif
])], [break])
done
ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1`
])
])
As #Ronny stated, there does not appear to be a standard way to determine the compiler vendor. Detecting a vendor is important during configure for tasks like working around Autoconf bugs during misdetection: CC: Warning: illegal use of -xarch option, illegal value ignored: sha.
#Ronny showed how to do it with preprocessor macros. We avoided that because of the way compilers pretend to be GCC. Both Clang and Intel's compiler defines __GNUC__, and probably others do it, too.
Here's how to do it with version strings in configure.ac:
## Determine the compiler's vendor.
COMPILER_VERSION=`"$CXX" --version 2>/dev/null`
## IBM xlC test if COMPILER_VERSION is empty
if test x"$COMPILER_VERSION" = "x"; then
COMPILER_VERSION=`"$CXX" -qversion 2>/dev/null`
fi
## SunCC test if COMPILER_VERSION is empty
if test x"$COMPILER_VERSION" = "x"; then
COMPILER_VERSION=`"$CXX" -V 2>&1`
fi
Then, the vendor can be used like:
IS_SUN_COMPILER=`echo $COMPILER_VERSION | $EGREP -i -c -E 'Sun C\+\+'`
echo "IS_SUN_COMPILER: $IS_SUN_COMPILER"
...
## This block handles SunCC.
if test "$IS_SUN_COMPILER" -ne "0"; then
...
fi
I want to begin my question with a disclaimer that I am beginner with c++.
My question is how does the preprocessor know which directories to look for when looking for header file.
I know that it searches in some specific predefined locations and whatever we pass as -I in the g++ compilation step. However what confuses me is some standard headers are picked up even if they are not in those locations.
I referred to the question at Finding out what the GCC include path is and I followed the steps there.
$ /usr/include % echo | cpp -Wp,-v
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/4.9/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
But I tried to locate the iostream and I see
$ locate iostream
/usr/include/c++/4.8/iostream
it is located at /usr/include/c++/4.8/iostream , but the search path ends at /usr/include . If it were any other header file, I would have to include it as
#include <c++/4.8/iostream>, but in all the programs I use #include <iostream> .
PS: The reason I am asking this question is because I accidentally deleted /usr/include/c++/4.9 directory, it used to work before deleting. But it is not picking up usr/include/c++/4.8/cstddef . I want to understand the procedure for picking up correct include paths of c++ preprocessor.
Thanks
They're compiled in. Make sure you specify the correct language.
$ echo | cpp -Wp,-v -x c++
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.9.2/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../include/c++/4.9.2
/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../include/c++/4.9.2/x86_64-redhat-linux
/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../include/c++/4.9.2/backward
/usr/lib/gcc/x86_64-redhat-linux/4.9.2/include
/usr/local/include
/usr/include
End of search list.
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
I have an eclipse c++ project that uses some c++11 features. It uses cmake for building so it is setup in eclipse as a project with existing makefiles.
It builds fine with the makefiles either in eclipse or from the command line. But I get syntax errors with atomic_bool saying the symbol can't be resolved. I have added -std=c++11 under 'C/C++ General -> Preprocessor Include Pattern -> Providers -> CDT GCC Built-in Compiler Settings' and I have the toolchain in eclipse set to MacOSX GCC.
Note: other c++11 things like thread or shared_ptr don't give any syntax errors.
The errors come from the <atomic> header where there is the preprocessor if statement
#if !__has_feature(cxx_atomic)
#error <atomic> is not implemented
#else
...
Everything below the #else is grayed out. So apparently __has_feature(cxx_atomic) evaluates to 0 according to eclipse. But if I check it from the command line it shows that it should evaluate to true.
$ echo '__has_feature(cxx_atomic)' | g++ -x c++ -std=c++11 -E -
# 1 "<stdin>"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 188 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "<stdin>" 2
1
Why does __has_feature(cxx_atomic) evaluate to false in Eclipse but not if I check the compiler itself?
Try a Enabling "Build output parser".
http://www.eclipse.org/forums/index.php/t/501479/
I encountered this issue too, other C++11 features are supported, but atomic does not.
I have the problem that when g++ is run in c++11 mode, some proprocessor macros are not expanded correct. This causes me troubles during the compilation of programs using Qt.
$ g++ --version
g++ (GCC) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The following snipped exposes the problem:
$ cat foo.cpp
//#include <QtGui>
#define QTOSTRING_HELPER(s) #s
#define QTOSTRING(s) QTOSTRING_HELPER(s)
#ifndef QT_NO_DEBUG
# define QLOCATION "\0"__FILE__":"QTOSTRING(__LINE__)
# define METHOD(a) qFlagLocation("0"#a QLOCATION)
# define SLOT(a) qFlagLocation("1"#a QLOCATION)
# define SIGNAL(a) qFlagLocation("2"#a QLOCATION)
#else
# define METHOD(a) "0"#a
# define SLOT(a) "1"#a
# define SIGNAL(a) "2"#a
#endif
METHOD(grml)
Preprocesing it without c++11 does the right thing.
$ g++ -E foo.cpp
# 1 "foo.cpp"
# 1 "<command-line>"
# 1 "foo.cpp"
# 15 "foo.cpp"
qFlagLocation("0""grml" "\0""foo.cpp"":""15")
But in C++11 mode the QTOSTRING macro does not get expanded, causing a compile error at the source line.
$ g++ -std=c++11 -E foo.cpp
# 1 "foo.cpp"
# 1 "<command-line>"
# 1 "foo.cpp"
# 15 "foo.cpp"
qFlagLocation("0""grml" "\0"__FILE__":"QTOSTRING(15))
Is this behavior intended, and what can I do to enable the expansion?
This is a known problem and the new GCC behaviour is intentional as a result of a new C++11 feature, namely user-defined literals. You can insert a space before __FILE__ and QTOSTRING to ensure it will always be treated as a separate token and thus expanded.
QT bugreport here.
The documentation tells me that /D command-line switch can be used to do this, like so:
CL /DDEBUG TEST.C
would define a DEBUG symbol, and
CL /DDEBUG=2 TEST.C
would give it the value 2.
But what do I do if I would like to get the equivalent of a string define, such as
#define DEBUG "abc"
?
Due to the way command line is parsed in Windows, you'll have to escape the quotes.
CL /DDEBUG=\"abc\" TEST.C
This works for me in VS2013:
/D_STRING="\"abc\""
then it is equivalent to
#define _STRING "abc"
Note, if you do
/D_STRING="abc"
It will be equivalent to
#define _STRING abc
Have you tried
CL /DDEBUG=abc TEST.C
or
CL /DDEBUG="abc" TEST.C
Thanks Glen, the second one could work on the command line, but the coworker I've asked this for eventually used this in the project definition (needing to escape the double-quotes and replace = with #):
/DDEBUG#\"abc\"
I don't have VC to test this for you, however, in principle the following should work:
CL /DSTRINGIFY(X)=#X /DDEBUG=STRINGIFY(abc) TEST.C
Update:
As highlighted by Kuber-Ober, VC doesn't seem to do the right thing here. Testing with a simple example, it generates:
const char * s = STRINGIFY(abc);
It may work with other compilers, for example the following g++ command line works:
g++ -D'STRINGIFY(X)=#X' -D'DEBUG=STRINGIFY(abc)' t.cc -E
# 1 "t.cc"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "t.cc"
const char * s = "abc";