The __FILE__ and __LINE__ macros are built into the C Pre-Processor, and are often used for printing debug output with file names and line numbers. I need something similar, but with just the name of the directory at the end of the path. For instance if my code is in:
/home/davidc/some/path/to/some/code/foo/bar I need a macro that will just give me "bar", if the code is in /home/davidc/some/path/to/some/code/foo/bee then I need it to give me "bee".
Any thoughts? (btw, this is for a C++ application).
Update: to be clear, I'm after a macro that will give me a string containing the directory name at compile-time, I don't want to do any string-processing at runtime.
If you are using GNU make to build your project, then you might be able to do something like this:
%.o: %.cpp
$(CC) $(CFLAGS) -D__DIR__="$(strip $(lastword $(subst /, , $(dir $(abspath $<)))))" -c $< -o $#
That has to be about the most God-awful thing that I have thought about doing in a Makefile in quite a while. I don't think that you will find a quick or clean way to do this within the confines of the compiler so I'd look for clever ways to inject the information into the compilation process.
Good luck.
There is no built in macro for that, but obviously you can write your own little parsing routine which takes a file and rips out the directory name for a given full pathed filename. Lets call this function:
extern std::string parseLastDir (const char *path);
Then you can make a macro like this:
#define __DIR__ parseLastDir (__FILE__)
which will sort of behave like what you want (it gives you a std::string instead of a char * so that cleaning up is better defined) with the relevant semantics (its results depends on the file in which its invoked, so that it always gets the right directory.)
Depending on your compiler/how your software is built, you can declare a macro to be the current or any path when you compile.
gcc -D__DIR__=/usr/src/test/ test.c
I've never used the MS compiler but I know there is a similar option for ICC as well.
gcc manpage
What you want is something similar to the unix
__BASE_FILE__
Take a look around http://theory.uwinnipeg.ca/localfiles/infofiles/gcc/cpp_13.html for it. I hope this helps.
EDIT: Attempt Two
How about using the #line preprocessor command. You can use it to change the filename variable too as you can see here: http://www.cppreference.com/wiki/preprocessor/line
How about changing your makefile/build system so that for .../bar/file.cc the compilation line will include -D__DIR__ bar. It should be easier...
Related
Does there exists a flag that I can pass to one of these preprocessors that causes the preprocessor to not resolve any macros in the code? I"m trying to use it just to concatenate any included header files into one file. Thanks!
From the manual
-fdirectives-only
When preprocessing, handle directives, but do not expand macros.
Read the full entry for complete details.
Add the -P option to suppress #line directives, e.g.
g++ -E -P -fdirectives-only ... file.cpp
or:
cpp -P -fdirectives-only ... file.cpp
AFAIK there is no such flag. If you only want to concatenate header files - go ahead and write a short program for this.
You may anyway need sch program as the preprocessor does more than including headers and extending macros. It is also responsible e.g. for concatenating string literals, so e.g. "This""And""That" is turned into "ThisAndThat". So you will get some unexpected changes in your sources anyway.
I'm trying to compile some C++ sources with GNU make using implicit rules, here's the content of my Makefile:
%.o: %.cpp
g++ -o $# $<
and the output of make
make: *** No targets. Stop.
Running make -d isn't very helping (I don't post the output which is quite verbose other than apparently useless). The folder is not empty.
You told Make how to build .o files, but you didn't tell it:
to build any .o files;
which .o files to build;
what to do with those .o files afterwards.
The rule doesn't mean that, when invoked without arguments, all .cpp files in the current directory or something will be compiled.
This one rule is just not enough.
You told make how to create arbitrary .o files from corresponding .cpp files, but you didn't tell it which files to create.
Analogy: I tell you, that, say, to make USB sticks, you'll need plastic, memory chips and a USB-A plug (now you know how to create any USB stick). But I don't say which USB sticks to create. This is exactly, what's happening here.
To solve your issue, you can say to make to create (for example) "asdf.o" by invoking make asdf.o, and it'll gladly do so, by using g++ -o asdf.o asdf.cpp.
You can also add an (de facto standard) all target, like so:
all: asdf.o fdsa.o [you get it]
And since the first target is the default, calling make is equivalent to calling make all, which in turn requires "asdf.o" and "fdsa.o", which will be created as described above.
Hello (I am using Windows, mingw g++ compiler and mingw32-make)
To generalize my question I would like to learn how to write a c++ source file as follows:
Assuming that foo.cpp depends on foo.h where foo.cpp is in src\ and foo.h is in include\
// foo.cpp
#include "foo.h"
Normally I would just write it like this
//foo.cpp
#include "..\include\foo.h"
but I have found that as my project grows, and I begin to need more organization, that this method isn't dynamic enough. Reason being I have to change every include for every file if I want to move foo.h to a new directory (say include\bar\foo.h). Is there a way for make to achieve this. If so can it be done for header file dependencies as well.
As a side note I am new to makefiles. I am not even sure that it knows these includes are there since they are within the code (in fact from what I understand it doesn't). That would lead me to an unfortunate secondary question, which is can make see these includes? If not is it possible to change it so that it can? Feel free to answer how you would approach this problem because I have a feeling I am going about this the wrong way by putting the includes in the file rather than linking them in the makefile.
The compiler is always looking into some default paths to look for .h-files. You can add your path.
For example gcc takes multiple -I arguments which contain a path. In your foo.cpp you do:
#include "foo.h"
and when compiling you say:
g++ -I../include foo.cpp -c [other options]
.
Regarding the second part of your question: The makefile and the call to make does not normally know anything about the files to be compiled and about your project. However there are several default variables and directives in make which lead to that impression: It could be, that in your environment you only need to change the CFLAGS or CPPFLAGS variable to add the -I-argument and it will work.
Patrick B has answered very well on how to make the compiler know where to include from, but not the following bit:
As a side note I am new to makefiles. I am not even sure that it knows
these includes are there since they are within the code (in fact from
what I understand it doesn't). That would lead me to an unfortunate
secondary question, which is can make see these includes? If not is it
possible to change it so that it can?
No, make doesn't understand what your source files contain, or how they depend on other files [make also doesn't really care if you are programming in C, C++, Fortran, Pascal, ADA, Lisp, Cobol or Haskell - as long as there is a "If you have a file like this, and want a file like that by doing something" relationship between files, make will sort it for you.
There are several ways to do this. You can manually add:
foo.cpp: foo.h
Or you can use a dependency file for your include-file, and let make built it automatically, by adding this, for example:
SOURCES = foo.cpp # Add any further source files here.
INCLUDES = -I../includes # Add other include directories if needed.
CFLAGS += ${INCLUDES}
TARGET = foo.exe # in Windows. Just foo in linux/MacOS.
all: ${TARGET} deps.mk
${TARGET}: ${SOURCES}
gcc -O $# $^
desp.mk: ${SOURCES}
gcc -MM ${INCLUDES} $^ > $#
include deps.mk
Note that makefiles are RELYING on indentation being tabs. This post uses spaces, so you will need to "tabify" the recepies. Also note that in a "proper" makefile, you'd make foo.o from foo.cpp, etc, and link all the different .o files together. That way, the compile is a fair bit quicker for large projects. I've simplified it for readability.
Maybe I should expand a little bit:
gcc -MM gives a list (to standard out) of the files that are being "compiled" and all of it's dependencies. It doesn't actually compile the code (and as long as the code is at least SOMEWHAT) close to being compileable, it will happily process your files.
For more details on gcc -MM and related, have a look at the GCC invocation documentation.
The $# and $&^ are what make calls "Automatic variables" - they expand to the "target" (easy to remember, as it looks sort of like a target for shooting arrows at or similar) and "all dependencies" (no visual clue here, I'm afraid - and every now and again, I have to remind myself) respectively. Check out here for more details.
My code is linking against several other libraries that are also developed at my company, one of these libraries is redefining several values from errno.h, I would like to be able to fix this, however I am having trouble finding the exact file that is redefining these values, I am want to know if there is a way to make the compiler tell me when a file has defined a particular value.
You can probably do it by adding -include errno.h to the command line that builds the library in question. Here's a quick example. I have a C program called "file.c":
#define ESRCH 8
That's it - then I compile with:
cc -c -include errno.h file.c
And presto, a compiler warning:
file.c:1:1: warning: "ESRCH" redefined
In file included from /usr/include/errno.h:23,
from <command-line>:0:
/usr/include/sys/errno.h:84:1: warning: this is the location of the previous definition
That will tell you where your bad definitions are.
Have you tried searching with grep?
If you don't want to search through all your headers for the particular #define, you could use
#undef YOUR_MANIFEST_CONSTANT
after each #include in your source module and then start removing them from the bottom up and see where your definitions come from.
Also, your compiler may tell you that a #define has been redefined. Turn all your warnings on.
With GCC I did something similar with:
g++ input.cc -dD -E > cpp.out
-dD tells cpp to print all defines where they were defined. And in the cpp output there are also markers for the include file names and the line numbers.
It is possible that some environments, I'm thinking IDE's here, have configuration options tied into the "project settings" rather than using a configuration header. If you work with a lot of other developers in a place where this behavior is NOT frowned on then you might also check your tool settings.
Most compilers will tell you where the problem is, you have to look and think about what the diagnostic notification is telling you.
Short of that, grep/findstr on *nix/Windows is your friend.
If that yields nothing then check for tool settings in your build system.
Some IDE's will jump to the correct location if you right click on the usage and select 'go to definition'.
Another option if you're really stuck is a command line option on the compiler. Most compilers have an option to output the assembler they generate when compiling C++ code.
You can view this assembler (which has comments letting you know the relative line number in the C++ source file). You don't have to understand the assembler but you can see what value was used and what files and definitions were included when the compiler ran. Check your compiler's documentation for the exact option to use
I have a perl script I'd like to filter my cpp/h files through before gcc processes them normally -- basically as an extra preprocessing step. Is there an easy way to do this? I realize I can feed the cpp files to the script and have gcc read the output from stdin, but this doesn't help with the header files.
The classic way to handle such a process is to treat the source code (input to the Perl filter) as a new language, with a new file suffix. You then tell make that the way to compile a C++ source file from this new file type is with the Perl script.
For example:
New suffix: .ccp
New rule (assuming .cc suffix):
.ccp.cc:
${FILTERSCRIPT} $<
Add the new suffix to the suffix list - with priority over the normal C++ rules.
The last point is the trickiest. If you just add the .ccp suffix to the list, then make won't really pay attention to changes in the .ccp file when the .cc file exists. You either have to remove the intermediate .cc file or ensure that .ccp appears before .cc in the suffixes list. (Note: if you write a '.ccp.o' rule without a '.ccp.cc' rule and don't ensure that that the '.cc' intermediate is cleaned up, then a rebuild after a compilation failure may mean that make only compiles the '.cc' file, which can be frustrating and confusing.)
If changing the suffix is not an option, then write a compilation script that does the filtering and invokes the C++ compiler directly.
The C and C++ preprocessor does not have any support for this kind of thing. The only way to handle this is to have your makefile (or whatever) process all the files through the perl script before calling the compiler. This is obviously very difficult, and is one very good reason for not designing architectures that need such a step. What are you doing that makes you think you need such a facility? There is probably a better solution that you are not aware of.
How about a wrapper around gcc that runs your Perl script and then calls gcc? Call it something like plgcc and set CC=plgcc in your makefile. Your script will have to be smart enough to process the include directives -- unless your script calls just the pre-processor to bring in the includes, does its thing, and then calls gcc.
GCC allows you to use your own preprocessor. You could set your script as the preprocessor then run the output through cpp (the normal gcc pre-processor). Look at the gcc manual for -B and -no-integrated-cpp command line options.
Warning - I have never tried it myself so don't know how messy it might be (bear in mind though that for many years lots of languages, including C++, were implemented as preprocessors to a c compiler so support shouldn't be too bad).
I've handled cases like this in the past by doing something like the following. This approach assumes that the unprocessed source code can be distinguished through a naming scheme of some sort, in this case suffixing the basename with _pp.
# These are your source files to be preprocessed
SRC_RAW = mysrc_pp.cpp
# These are the source files after preprocessing
SRC_PP = $(patsubst %_pp.cpp, %.cpp, $(SRC_RAW))
ALL_SRC = $(SRC) main.cpp other.cpp
OBJ = $(patsubst %.cpp, %.o, $(ALL_SRC))
$(SRC): %.cpp: %_pp.cpp
$(PERL) $< > $#
$(OBJ): %.o: %.cpp
$(CXX) ...
This does not, however, handle the case where you have header files which need preprocessing. In that case you would need similar rules for creating them.