Background:
I am putting together a test environment for an embedded project. Since it's an embedded project it tries to access hardware registers e.g. ADC results, timer settings, interrupt flags...
These registers are implemented automatically by Halcogen (it's a TI processor), as defines pointing to specific addresses.
#pragma system_include
#ifndef __REG_FLASH_H__
#define __REG_FLASH_H__
/* USER CODE BEGIN (0) */
/* USER CODE END */
#include "sys_common.h"
typedef volatile struct flashWBase
{
uint32 FRDCNTL; /* 0x0000 */
uint32 rsvd1; /* 0x0004 */
.
.
.
uint32 EESTATUS; /* 0x031C */
uint32 EEUNCERRADD; /* 0x0320 */
} flashWBASE_t;
#define flashWREG ((flashWBASE_t *)(0xFFF87000U)) //<--- This one
#endif
My attempted solution:
In order to compile and run this code on a MinGW Win7 machine these specific addresses need to be re-defined to be pointing to observable and mutable variables. I have a Python script that analyzes the source code; creating a new header file using the same name in a common directory containing:
#ifndef _COMMON_INCLUDES_REG_FLASH_H_
#define _COMMON_INCLUDES_REG_FLASH_H_
#include "..\..\W2_Library\Halcogen\Include\reg_flash.h" //<--- original Halcogen header
#undef flashWREG
flashWBASE_t _flashWREG;
#define flashWREG (&_flashWREG)
#endif
I have made many attempts using -I-, -I<dir> and -iquote to redirect inclusion of the headers getting farthest using the deprecated -I- to make GCC ignore the . directory. I would however rather have my Common folder precede the . than ignoring all together. Adding a -I. does not seem to be the same thing, I get the feeling it expands to the directory of the source code and doesn't stay "relative" as GCC delves deeper into the inclusion tree like the original . do.
Letting my Python script clone the entire header, replacing only the HW address with a variable, could be a solution. Just redefining the register defines in a separate header does however feel less prone to break.
Question:
Is there any other ways to alter the search order?
I have read several questions about -I- but none has really had any answers as to how you get around the behaviour. This question is pretty close but unlike that user, I am not using precompiled headers.
There are a few assumptions above and please correct me if they are wrong!
The problem you are having is with #include "..." as opposed to #include <...>
With a normal C compiler, using the " form always searches in the same directory as the current file, and then looks in the include path set by -I. If you want to search somewhere else before looking in the current file's directory, there's no easy way to do it.
You can use gcc's -I- to inhibit searching in the current file's directory, and add other directories to use only for " include files (not for <>), but if you use that, there's no way to get back the behavior of searching in the current file's directory.
You can try something like:
-ICommon -I. -I- -Iwhatever
This will search for " includes first in Common, then in the current working directory, then in whatever (and the rest of the normal path), while <> will start in whatever. Unfortunately, it will never search in the current file's directory, if that is different from the current working directory.
-I- is also deprecated, so may go away soon.
Related
I have a file called assert.h which defines several assertion macros. The project is called Core and lives in a folder with the same name. However, this file lives in Core/hul, which is a submodule of the project that implements some abstract utilities. Here's an excerpt of the file:
#if defined(HUL_DEBUG)
# if defined(HUL_TEST)
# define HUL_ASSERT(e) HUL_TEST_ASSERT(e)
# else
# include <assert.h>
# define HUL_ASSERT(e) assert(e)
# endif
#else
# define HUL_ASSERT(e) /* empty, do nothing */
#endif
As you can see, when HUL_TEST is defined assertion macros expand to a unit test assertion callback. That works fine. When compiling for release (e.g. HUL_DEBUG is not defined) it does nothing. Also fine. When compiling for debug (without testing), it includes the system's assert.h and defines a macro that expands to assert. Everything OK so far.
The problem is that regardless of including <hul/assert.h> or <assert.h> it's always hul/assert.h that is included, which is not what I want. This is one of the reasons that hul/assert.h is qualified under the hul folder.
The obvious first thing to check is Other C Flags and Header Search Paths. But the later is empty and the former is as follows:
-I../../include/Core
-I../../test/include/Core
-I../../test/include
As you can see, Core/hul is not included, so #include <assert.h> should not resolve to hul/assert.h. The question is, why does it? Am I missing some configuration?
Note: of course I could change the file's name, but I rather understand why this is happening. This framework will still grow immensely in number of files and I don't want to be worrying about this kind of conflicts.
set USE_HEADERMAP = NO. When set to YES, XCode uses a dictionary that maps a header file name to a path where to find in order to speed up compilation. So regardless where you place your header file, if it has found his way into this map it will be found forth on.
Another way would be to use absolute paths for all user header files, e.g. #include "./assert.h" (which should give you an error if the file is not located directly in the project directory or any manually defines user header search path).
Hope it helps;
I am working on the source code of a Unix-based kernel. I noticed that the last line of each source code file (.c or .h) is a specific line with the following format:
__SRCVERSION( "$URL: ... $ $Rev: 219996 $" )
The URL points to the web address of the same file. I'm wondering what does that mean, and what is it actually for? Would it be any problem if I delete this line from all of my source code files?
Macros like this are often used to embed versioning information into binaries when they are compiled. They can be updated automatically when fetched out of a source control system with appropriate rules. Removing them shouldn't cause any harm, but you will lose the benefit of being able to search a binary to identify which versions of your source files were used to compile it.
As #Keith Thompson says below, it may also be possible to configure your build to not embed the information. Below is an example of the macro definition taken from here (different systems are likely to have different definitions). You can see that it uses the __USESRCVERSION definition to decide which version of the __SRCVERSION macro is used:
#ifndef __USESRCVERSION
#define __SRCVERSION(id)
#else /* __USESRCVERSION */
#ifdef __QNXNTO__
#if defined __SRCVERSION
#undef __SRCVERSION
#endif /*__SRCVERSION */
#define __SRCVERSION(id) \
__asm__(".section .ident,\"SM\",#progbits,1"); \
__asm__(".asciz " #id); \
__asm__(".previous");
#endif /* __QNXNTO__ */
#endif /* __USESRCVERSION */
I know it is possible to specify #include filepaths either relative to the directory the file is located in, as an absolute file path, or relative to any of the directories in the $PATH system variable. Is there a way to instead specify it relative to the user's current directory when the program is compiled? Let's say I have the following file structure:
|--dir_a/
| |--a.c
| |--a.h
|--dir_b/
| |--b.c
| |--b.h
|--makefile
Now let's say I want to #include the file dir_a/a.h from dir_b/b.h. Using the location of dir_b/b.h, this can be written like this:
#include ../dir_a/a.h
However, this approach has a major flaw in my opinion since it hardcodes the locations of files relative to each other, meaning that relocating a file would require updating the file path everywhere that file was included from.
Using absolute file paths would avoid this problem, but would instead hardcode the location of the project within the filesystem, which seems like bad practice.
Finally, using the <> tags to specify the file path isn't feasible either since I can't assume the project will be listed in the $PATH variable.
So what I want to do is to be able to specify the paths relative to where the user compiles from (or even better, from the location of the makefile). In the above example, this would let me use the following statement to #include dir_a/a.h from dir_b/b.h:
#include dir_a/a.h
This I think would be the ideal solution. It would make the #include statements more consistent and easier to follow, as well as avoid the drawbacks I listed above. Is it possible to do this in any way, eg. with a compiler flag or something? I'm using gcc as my compiler.
If you consistently use <> includes, then the -I options in the makefile should be enough. The directory layout shows only one makefile, in the parent directory. That could use
-Idir_a -Idir_b
in the compiler options, and the .c files could just do
#include <a.h>
#include <b.h>
One of the problems with quoted includes is that their behavior with other compilers may differ, as noted in What is the difference between #include <filename> and #include “filename”? (the standard was not explicit enough). Using a gcc extension probably does not improve that situation.
I managed to solve my problem.
The first part of the solution involves specifying the -iquote flag in gcc when compiling. From man gcc:
-iquotedir
Add the directory dir to the head of the list of directories to be searched for header files only for the case of #include "file"; they are not searched for #include <file>, otherwise just like -I.
The second part of the puzzle was how to get the path to the makefile within the makefile itself. This answer worked for me. I'm pasting the solution here for convenience:
ROOT_DIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
edit: While this approach works, this answer is more cross-compiler friendly, so I'm personally going to use that.
Yes. Any include file, which is not directly in your include path specified in your project linker settings, should have all subfolders up to it specified, like:
#include "first/second/third/folder/library.h"
I have a set of includes that reside in a far off directory meaning that including them requires a long include, such as:
#include "../../Path/to/my/file.h"
Where I have multiple of these it becomes a bit inconvenient so I am thinking I may be able to use a #define for the directory path and then concat the file name that I need, i.e.
#define DIR "../../Path/to/my/"
#define FILE1 "file.h"
#define FILE2 "anotherFile.h"
#include DIR FILE1 // should end up same as line in first example after pre-proc
However this does not work... is there anyway to concatenate within the workings of the C pre-processor suitable for this?
The compiler will do macro replacement on an #include line (per C 2011 [N1570] 6.10.2 4), but the semantics are not fully defined and cannot be used to concatenate file path components without additional assistance from the C implementation. So about all this allows you to do is some simple substitution that provides a complete path, such as:
#define MyPath "../../path/to/my/file.h"
#include MyPath
What you can do with most compilers and operating systems is:
Tell the compiler what directories to search for included files (as with GCC’s -I switch).
Create symbolic links to other directories, so that #include "FancyStuff/file.h" becomes equivalent to ../../path/to/FancyStuff because there is a symbolic link named FancyStuff that points to the longer path.
You can't customise the search path for include files like this, but you can tell the compiler where to look for include files. Many compilers -I option for that, e.g.:
gcc -c stuff.c -I/path/to/my/ -I/path/to/other/
If that makes your compilation command too long, you should write a Makefile or, if you are working in Visual Studio or similar IDE, customise the search path in your project settings.
I am trying to get some code that I acquired from a repository to work on my system.
In one of the C files, it contains an absolute path to a header:
#include "/home/user/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/x86_64-linux/ruby/config.h"
Because this file and directory does not exist on my system, compiling the source code fails.
I assume if I change this to point at my personal location of config.h, it will succeed but then fail on others' systems.
Is there a way to point at some symbolic link that the system will then use the proper location for such a file? What is the best way to approach this situation?
Change it to #include "ruby/config.h", and then add -I/home/user/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/x86_64-linux/ (or whatever your location is) to your compiler options. This tells the preprocessor to add that directory to the list of directories to search when looking for #includes.
To solve the portability you can then change whatever generates the makefile to take this path as an option/argument, or you can just put it in a variable at the top of the makefile and ask people to change it:
RUBY_LOCATION = /home/user/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/x86_64-linux/
CFLAGS = -Wall -I${RUBY_LOCATION}