C_INCLUDE_PATH equivalent for Fortran? - fortran

Is there a Fortran equivalent to the standard environment variables C_INCLUDE_PATH and CPLUS_INCLUDE_PATH?

gfortran does not use an environment variable to modify the search path for modules.
Much as C_INCLUDE_PATH and CPLUS_INCLUDE_PATH affect the preprocessor's search path, CPATH (and C_INCLUDE_PATH) can be used when invoking the preprocessor with gfortran. However, the use statement and include line are not part of the preprocessing stage: these variables will allow files to be found with #include but not otherwise.
The Fortran language more widely does not specify such things. Other compilers beyond the tagged gfortran may use an environment variable of some name in the desired way.

Related

How to detect OS without directive ifdef?

I have to reset system date and time either on Linux, or on Windows.
How do I check OS without using ifdef, or if defined?
With CMake, you can conditionally add files to a target by using generator expressions. With that, you can isolate any platform-specific code in files, and use them in your build specification as follows.
add_executable(reset-time
$<$<PLATFORM_ID:Darwin>:resettime-macos.cpp>
$<$<PLATFORM_ID:Linux>:resettime-linux.cpp>
$<$<PLATFORM_ID:Windows>:resettime-windows.cpp>)
And as #eeroika pointed out in the comments, a good alternative is
add_executable(reset-time
resettime-$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>.cpp)
as it requires not adjustment (of the CMakeLists.txt) when porting your project to a new system and you can catch a missing implementation file earlier, i.e., before linking.
You could set a global macro definition to the compiler based on which operating system you are compiling for. For example -D IS_WINDOWS=1. You could then use #if IS_WINDOWS instead of #ifdef. I don't know why this would be useful but it achieves what you asked.

c++ - #ifdef macro

I can see
#ifdef <token>
code;
#endif
to be included, but I can't find it defined in any of the headers it includes. Is there any other mechanism with which the token could be defined?
Firstly, there are macros that are implicitly defined by the compiler (for example, __cplusplus). Some of these are standard, and some are compiler-specific extensions. See your compiler manual for the full list.
Additionally, most compilers allow defining macros on the command line. The exact mechanism is compiler-dependent, but often takes the form of a -D or /D command-line option. For example, see the gcc manual:
-D name
Predefine name as a macro, with definition 1.
-D name=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a `#define' directive. In particular, the definition will be truncated by embedded newline characters.
If you are invoking the preprocessor from a shell or shell-like program you may need to use the shell's quoting syntax to protect characters such as spaces that have a meaning in the shell syntax.
If you wish to define a function-like macro on the command line, write its argument list with surrounding parentheses before the equals sign (if any). Parentheses are meaningful to most shells, so you will need to quote the option. With sh and csh, -D'name(args...)=definition' works.
For Microsoft Visual C++, see http://msdn.microsoft.com/en-us/library/hhzbb5c8(v=vs.80).aspx
Some compilers provide convenient tools for figuring out where a particular preprocessor macro is defined. See, for example, How to know (in GCC) when given macro/preprocessor symbol gets declared?
Most (all?) compilers allow defining values with flags (-D in gcc), also some may be set by the compiler itself.
Yes, of course, preprocessor directives can be set with the compiler. For example, gcc lets you add directives in the command line, you can specify directives in the project settings in Visual Studio. Also think about __cplusplus, or _LINE_ of _FILE_. Those aren't defined anywhere, yet they exist. Also _DEBUG or UNICODE which are set up by the MSVS environment.

Linux Global Includes Path

I am trying to use OpenBabel and am experiencing great difficulty with setting up a global search path for include files. I have successfully linked to the libraries with $LD_LIBRARY_PATH, but when compiling with the GNU C++ compiler, it cannot find the include files. Is there a global include environment variable on Linux, and if so, what is it?
You could give the include path to GCC using the option -I:
g++ -I/path/to/the/include/dir blabla
Please note that also the library dir may be bassed via -L option -L/path/to/lib/dir. LD_LIBRARY_PATH is usually considered a dirty hack.
You can have multiple -I (and -L) options:
g++ -I/dir/include1 -I/dir/include2
If you check the manpage for cpp (the C Preprocessor), it state that it will treat the following environment variables like the -I option mentioned above:
CPATH
C_INCLUDE_PATH
CPLUS_INCLUDE_PATH
Now, I believe that current g++ and gcc use an inbuilt cpp, but I would expect that it would function like the stand alone cpp, and respect these environment variables.

How do compilers know where to find #include <stdio.h>?

I am wondering how compilers on Mac OS X, Windows and Linux know where to find the C header files.
Specifically I am wondering how it knows where to find the #include with the <> brackets.
#include "/Users/Brock/Desktop/Myfile.h" // absolute reference
#include <stdio.h> // system relative reference?
I assume there is a text file on the system that it consults. How does it know where to look for the headers? Is it possible to modify this file, if so where does this file reside on the operating system?
When the compiler is built, it knows about a few standard locations to look for header file. Some of them are independent of where the compiler is installed (such as /usr/include, /usr/local/include, etc.) and some of the are based on where the compiler is installed (which for gcc, is controlled by the --prefix option when running configure).
Locations like /usr/include are well known and 'knowledge' of that location is built into gcc. Locations like /usr/local/include is not considered completely standard and can be set when gcc is built with the --with-local-prefix option of configure.
That said, you can add new directories for where to search for include files using the compiler -I command line option. When trying to include a file, it will look in the directories specified with the -I flag before the directories I talked about in the first paragraph.
The OS does not know where look for these files — the compiler does (or more accurately, the preprocessor). It has a set of search paths where it knows to look for headers, much like your command shell has a set of places where it will look for programs to execute when you type in a name. The GCC documentation explains how that compiler does it and how these search paths can be changed.
The location of the file is system dependent. Indeed, the file might be precompiled, or it may not even exist—the compiler may have it as a 'built-in'. On my macbook, I see that there's such a file in /usr/include/c++/4.2.1/iostream, but you shouldn't rely on it, and it's definitely a bad idea to edit it.
If you were using g++, you could do something like this to find out what include paths were searched:
touch empty.cpp
g++ -v empty.cpp
I don't know if there's an equivalent for Xcode. Maybe that will work since Xcode is based on GCC?
In Visual Studio, it's either in the project settings if you use the IDE, or in the %INCLUDE% environment variable if you use the command line.
You should avoid #include-ing files using absolute paths. The compiler searches for the include files in various directories and includes files, starting from each directory. For example;
#include <boost/tokenizer.hpp>
Works because the boost root directory contains a folder called 'boost' and that folder is either in your default include path or you did something like.
g++ -I$BOOST_ROOT {blah, blah}
It is C and C++ standard that the UNIX separator '/' will work the same way for all systems, regardless of what the host system actually uses to denote directories. As others of mentioned, occasionally #include doesn't actually include a real file at all.

include boost header file using "" or <>

Why does tuple documentation say to use, for example:
#include "boost/tuple/tuple.hpp"
and not
#include <boost/tuple/tuple.hpp>
I know that it's not probable my code will have a file called "boost/tuple/tuple.hpp",
but using include <> states explicitly not to look in the curent directory.
So what is the reason?
Using <> does not mean "don't look in the current directory" - It means look in an implementation defined place and then look somewhere else, also implementation defined. Either, both or neither of these could be the current directory. This is one of the more useless bits of the C++ standard.
The historical meaning of <somefile> is to look in the system-standard places. With "somefile" it means look in the current directory, plus some other places.
Afaik the reason is to differentiate between headers that belong to an application and those which are from external libraries. I can't say why they have not used this convention. It is a only a convention and not a rule.
Perhaps someone should raise this issue with the Boost maintainers?
Use <...> for boost. This is not Your code. Unless your code is boost.
Use "...." for your header files, which you inevitably have in every C++ program. This is for the reader, not for the compiler.
From msdn:
Quoted form
This form instructs the preprocessor
to look for include files in the same
directory of the file that contains
the #include statement, and then in
the directories of any files that
include (#include) that file. The
preprocessor then searches along the
path specified by the /I compiler
option, then along paths specified by
the INCLUDE environment variable.
Angle-bracket form
This form instructs the preprocessor
to search for include files first
along the path specified by the /I
compiler option, then, when compiling
from the command line, along the path
specified by the INCLUDE environment
variable.
Are you asking what the difference between the two styles of inclusion is, or for Boost's rationale? Since others have spoken regarding the difference, I'll just add my take on the latter issue:
I don't believe either is more correct, in general. It depends on how your project is structured with respect to its dependencies. For example, in my projects I typically include the relevant bits of Boost, et cetera, in a subdirectory of the project and thus tend to prefer the #include "" form. If you want to pick up the Boost installation from a more global location, you'd prefer the #include <> form.