I am trying to generate output file by the use of macro in source file.
Whatever a macro name is, generate the final .exe file by using the macro name.
#include <iostream>
#define Apple
//#define Banana
//#define Mango
int main()
{
...
}
How could i generate an output file name like Apple.exe ?
compiler: g++
OS: windows
You cannot steer the name of the final linker artifacts (executable in your case) from within the source code.
This needs to be done using the -o <filename> linker flag, thus in your case
> g++ -o Banana.exe main.cpp -DNAME=Banana
To control this more easily you can define these as variables in a makefile, e.g. like
# Comment the current, and uncomment a different definiton to change the executables
# name and the macro definition for NAME
FINAL_NAME = Banana
# FINAL_NAME = Apple
# FINAL_NAME = Mango
$(FINAL_NAME).exe : main.cpp
g++ -o $(FINAL_NAME).exe main.cpp -DNAME=$(FINAL_NAME)
Related
I have 2 Dirs and 3 header files stored in them, as follows:
Dir A : contains Header files A and C
Dir B : contains Header file B
Dirs A and B are sub-directories of a dir named Apps (which is a subdir of some other dirs).
Basically, the problem occurred in a similar situation, from which I have isolated the problem. Hence, the C++ source files shown below are trivial:
Header file A.h:
#ifndef A_H
#define A_H
class A
{
};
#endif /// A_H
Header file C.h:
#ifndef C_H
#define C_H
#include "B.h"
class C
{
};
Tester for A.h, viz. TestA.cpp:
/** TestA.cpp */
#include "A.h"
/// ...
int main()
{
}
Tester for C.h, viz. TestC.cpp:
/** TestC.cpp */
#include "C.h"
/// ...
int main()
{
}
Dir B contains 1 C++ header file B.h and its tester TestB.cpp, both trivial:
Header file B.h:
#ifndef B_H
#define B_H
#include "A.h"
class B
{
};
#endif /// B_H
Tester for B.h, viz. TestB.cpp:
/** TestB.cpp */
#include "B.h"
/// ...
int main()
{
}
The 3 testers TestA.cpp, TestB.cpp and TestC.cpp have 3 makefiles: MakeA, MakeB and MakeC respectively. MakeA and MakeC are in dir A and MakeB is in dir B, as expected.
I am not showing MakeA and MakeB, since they work correctly.
The error occurs in MakeC:
CPP = g++
OFLAG = -o
CFLAG = -std=c++11 -c
PROG1 = TestC
HC = C
HB = B
HA = A
HBDIR = ../B/
HADIR = ./
IHBDIR = -I$(HBDIR)
IHADIR = -I$(HADIR)
all : $(PROG1).o $(PROG1).exe run1
$(PROG1).o : $(PROG1).cpp $(HADIR)$(HC).h $(HBDIR)$(HB).h $(HADIR)$(HA).h
$(CPP) $(CFLAG) $(IHADIR) $(IHBDIR) $<
$(PROG1).exe : $(PROG1).o
$(CPP) $(OFLAG) $# $^
run1:
$(PROG1)
This make file is unable to locate header file A (which is #included by header file B) and gives the following error:
In file ...
../B/B.h fatal error: A.h : no such file or directory
#include "A.h"
compilation terminated
Evidently, make is searching for A.h in B.h's dir (since B.h #includes A.h). However, I have defined the symbol HADIR (as ./), which should have caused make to search in the default dir, which is Dir A.
Please note:
1) The header file references are simple and linear : A.h is #included by B.h which is #included by C.h.
2) I don't wish to hard-code dir paths in the source files. They must be stored only in the makefiles, since that's one of the purposes of makefiles.
3) There are 2 solutions to the problem that I know of:
a) Relocate C.h, its tester and makefile to a dir C. However, I don't want to do this, since A.h and C.h are semantically related.
b) In MakeC, define HADIR as ../A, rather than ./ But I don't understand why I should do that.
The BAT file that invokes the make utility with MakeC as input makefile, is as follows:
cd /f/Files/C/SW/Applications/Samples/C++Samples/Introductory/
Classes/Apps/A/
make -f MakeC
Thanks.
See this link for information on which paths include searches. Assuming you used the form include "file" (with quotes, not #include <file>, which is slightly different):
By default, the preprocessor looks for header files included by the
quote form of the directive #include "file" first relative to the
directory of the current file, and then in a preconfigured list of
standard system directories. For example, if /usr/include/sys/stat.h
contains #include "types.h", GCC looks for types.h first in
/usr/include/sys, then in its usual search path.
...
There are a number of command-line options you can use to add
additional directories to the search path. The most commonly-used
option is -Idir, which causes dir to be searched after the current
directory (for the quote form of the directive) and ahead of the
standard system directories. You can specify multiple -I options on
the command line, in which case the directories are searched in
left-to-right order.
notice that
directory of the current file
refers to the directory that gcc was invoked from, as opposed to the directory of the source file (not the best wording). So, if you invoke gcc from the directory of your .c file, you would want to add a -IA -IB flag to your compiler options, and then do not include paths in your #include directives (assuming gcc is being called from the directory of the .c file).
If you do want to include paths, they must be relative to the directory from which gcc was invoked, or one of the other include paths specified by a -I option.
---- EDIT -----
OK, I just read your updates, and it seems that TestC.c is in directory A, which I didn't get from your original post This means you're compiling from directory A. In this case I cannot reproduce your problem (at least not on my linux system):
[157]~/tmp/tmp9/A> find .. -type f -exec echo "------ " {} " ------" \; -exec more {} \;
------ ../A/A.h ------
#pragma message "A.h"
// blank
------ ../A/C.h ------
#pragma message "C.h"
#include "B.h"
------ ../A/testC.c ------
#pragma "message file.c"
#include "C.h"
int main() {}
------ ../B/B.h ------
#pragma message B.H
#include "A.h"
[157]~/tmp/tmp9/A> gcc -I. -I../B testC.c
In file included from testC.c:2:
C.h:1: note: #pragma message: C.h
In file included from C.h:2,
from testC.c:2:
../B/B.h:1: warning: expected a string after ‘#pragma message’
In file included from ../B/B.h:2,
from C.h:2,
from testC.c:2:
./A.h:1: note: #pragma message: A.h
[157]~/tmp/tmp9/A>
Your make command should echo the command used to build your test program -- attach that output to the question.
Per https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_2.html#SEC6:
Section 2.1: Include Syntax
[#include with quotation marks] is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the same directories used for <file>
Since we're discussing an include-with-quotes from another header, we must figure out what is considered the "current file". Our options are:
the source file that included the original header
the original header itself (that now includes the subject header)
Section 2.2: Include Operation
The `#include' directive works by directing the C preprocessor to scan the specified file as input before continuing with the rest of the current file
To me, this wording implies that #include acts as an interruption to the processing of "current file", during which the included file becomes "current". (Consider how this would have been written if the #include were interpreted as expanding into or as a part of the #including file.) Also, if the quotation-mark version of #include were interpreted in the context of the #including file, it would break all the time and be mostly useless.
So the #include "A.h" within B.h looks for A.h relative to the location of B.h. But $HADIR is not equal to $HBDIR so this lookup fails.
Note however that -I adds to the list of places that should be searched by #include-with-angle-brackets...which should also be searched after "directory of the current file" for #include-with-quotation-marks...so your compiler is doing something weird with it's search.
I also confirm that gcc 4.8.5 does not repro your issue. Here's my test setup relative to the directory Prog
[Prog]$ find ..
../Prog
../Prog/A.h
../Prog/MakeC
../Prog/TestA.cpp
../Prog/TestC.cpp
../Prog/C.h
../B
../B/B.h
../B/TestB.cpp
Then building yields:
[Prog]$ make -f MakeC
g++ -std=c++11 -c -I./ -I../B/ TestC.cpp
g++ -o TestC.exe TestC.o
TestC
What compiler are you using? (I'd bet a fair sum it's either old (circa gcc 2.9.6) or is customized by a vendor to target an embedded plaform) I've seen interesting include path checks with some of these.
Here's a small contrived demo to show the proper behavior of #include-with-quotes:
inc/a.h
#pragma once
#include "b.h"
inc/b.h
#pragma once
extern int garbage;
test.c
#include "inc/a.h"
Then
$ gcc -E test.c
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.c"
# 1 "inc/a.h" 1
# 1 "inc/b.h" 1
extern int garbage;
# 4 "inc/a.h" 2
# 1 "test.c" 2
Note the main .c file includes "inc/a.h" directly, and there is no search path given on the compiler commandline, yet it still finds "b.h".
OK, I've finally solved the problem as follows:
1) Make the BAT file set the default dir to 1 dir above the A and B dirs, ie, to the Apps dir, and invoke the make utility from there:
cd /f/Files/C/SW/Applications/Samples/C++Samples/Introductory/Classes/Apps/
make -f A/MakeC
2) Modify the makefile to access each header explicitly from the dir in which it is stored, create the obj and exe file in a specified dir and invoke the exe file in the specified dir:
CPP = g++
OFLAG = -o
CFLAG = -std=c++11 -c
# BAT file invoking MakeC sets default to ... Classes/Apps/
HADIR = ./A/
HBDIR = ./B/
# HADIR contains HA and HC
# HBDIR contains HB
HA = A
HC = C
HB = B
PROG1 = TestC
IHADIR = -I$(HADIR)
IHBDIR = -I$(HBDIR)
all : $(PROG1).o $(PROG1).exe run1
$(PROG1).o : $(HADIR)$(PROG1).cpp $(HADIR)$(HC).h $(HBDIR)$(HB).h $(HADIR)$(HA).h
# Create obj file in HADIR explicitly
$(CPP) $(OFLAG) $(HADIR)$# $(CFLAG) $(IHADIR) $(IHBDIR) $<
$(PROG1).exe : $(HADIR)$(PROG1).o
# Create exe file in HADIR explicitly
$(CPP) $(OFLAG) $(HADIR)$# $^
clean:
# Specify dir explicitly
rm $(HADIR)*.exe $(HADIR)*.o
run1:
# Specify dir explicitly
$(HADIR)$(PROG1)
As I've stated, I'm using g++ 4.8.1.
What worked for me, was to have the invoking BAT file set the default dir to one level above the dirs that contain the source files and in the makefile, specify the dirs explicitly.
---- EDIT ----
I'd like to suggest a possible reason for why this works.
First, notice that originally, the HADIR variable was set to ./ (the default dir).
As #lockcmpxchg8b said, the "default dir" could be interpreted as (a) wrt the original file or (b) the #included header file. These are the only 2 possibilities. Since the compiler can't find the #included header, it means it has selected the wrong possibility. This is obviously a version-specific gcc problem, since others can't repro the problem on later gcc versions.
Then, the solution is to avoid using ./ as a value for a dir symbol such as HADIR. Instead set the default dir outside make to another dir. In this case, it was done to the dir one level above A and B (viz. Apps). Then, the makefile's dir symbols can be made all wrt to that dir and would obviously not be ./
With values other than ./ (interpreted as the default dir by the compiler), the compiler interprets the value for the dir symbol as desired.
I think in your "B.h", you should do: #include "(Adir)/A.h"
It seems like "A.h" is in a adjacent directory of the "B.h" directory. so when "B.h" tries to look for it in its current directory, it can't find it.
I'm guessing #include "../A/A.h"
Environment
Ubuntu 16.04
G++ 5.3.1
I have a header file with the following intended to include a different .h file depending on platform:
#ifdef _WIN32
#include "curses.h"
#else
#include <ncurses.h>
#endif
This works fine in windows but in Ubuntu I get errors about the curses.h file:
In file included from /usr/include/unctrl.h:54:0,
from /usr/include/curses.h:1694,
from headers/command_window.h:8,
from command_window.cpp:1:
headers/curses.h:900:19: error: macro "clear" passed 1 arguments, but takes just 0
int clear(void);
This when compiling with:
g++ -g -lncurses -std=c++11 -Iheaders -c -o command_window.o command_window.cpp
Why is headers/curses.h, which is the windows specific file for PDCurses being involved here at all?
/usr/include/unctrl.h contains this line:
#include <curses.h>
And since you've told the compiler to look in your headers/ folder for header files with the -Iheaders flag , the compiler picks up curses.h in that folder.
So you need to drop the -Iheaders flag (and e.g. use #include "headers/header_name.h") or you need to rename your headers/curses.h to not collide with /usr/include/curses.h
In your version of g++, the -I option is not the correct way to add application-specific header files (those that shouldn't be found by #include in system headers) to the search path (this change surprised me as well).
Instead, you should use -iquote headers.
See this answer: How to tell g++ compiler where to search for include files? and this official documentation
[As Cornstalks explained below, I'm trying to strip a header prefix that's used in an #include. So it appears this question is not a duplicate of How to make g++ search for header files in a specific directory?]
I'm making some changes to a library. I have the library locally, so its not installed in its customary system location.
I have a test source file and its sided-by-side with the library. The test file has a bunch of includes like:
#include <foo/libfoo.h>
And it also has a bunch of customary includes, like:
#include <iostream>
I'm trying to compile the test file using:
$ g++ ecies-test.c++ -I. -o ecies-test.exe ./libcryptopp.a
And (the space between -iquote . does not appear to make a difference):
$ g++ ecies-test.c++ -I. -iquote . -o ecies-test.exe ./libcryptopp.a
The problem I am having is I don't know how to tell g++ that <foo/libfoo.h> means "./libfoo.h". Effectively, I'm trying to strip the prefix used to include the header. I've looked in the manual under 2.3 Search Path, but it does not really discuss this scenario.
I have about 60 extra test files I use for the library. And each has 10 or 20 includes like this. So I can't go through and change #include <foo/libfoo.h> to #include "./libfoo.h" in 500 or 600 places.
I tried #rici's work around by creating the fictitious directory structure, but it broke GDB debugging. GDB cannot find symbols for class members, so I can't set breakpoints to debug the code I am attempting to modify.
How do I tell the compiler to look in PWD for system includes?
Below is a typical error. ECIES_FIPS is in my local copy of the library.
$ g++ -DNDEBUG=1 -g3 -Os -Wall -Wextra -I. -iquote . ecies-test.c++ -o ecies-test.exe ./libcryptopp.a
ecies-test.c++:29:17: error: no member named 'ECIES_FIPS' in namespace
'CryptoPP'
using CryptoPP::ECIES_FIPS;
~~~~~~~~~~^
ecies-test.c++:44:5: error: use of undeclared identifier 'ECIES_FIPS'
ECIES_FIPS<ECP>::Decryptor decryptor(prng, ASN1::secp256r1());
^
ecies-test.c++:44:16: error: 'ECP' does not refer to a value
ECIES_FIPS<ECP>::Decryptor decryptor(prng, ASN1::secp256r1());
^
/usr/local/include/cryptopp/ecp.h:30:20: note: declared here
class CRYPTOPP_DLL ECP : public AbstractGroup<ECPPoint>
...
In case it matters:
$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin12.6.0
Thread model: posix
There is no option which tells gcc to ignore directory prefixes in include paths. If your program contains #include <foo/header.h>, there must be some path_prefix in the include list such that path_prefix/foo/header.h resolves to the desired file.
While you cannot configure gcc to ignore the foo, you can certainly modify the filesystem as you please. All you need is that there be somewhere a directory foo which maps onto the directory where the header files are stored. Then you can add the parent of that directory to the search path.
For example:
mkdir /tmp/fake
ln -s /path/to/directory/containing/header /tmp/fake/foo
gcc -I /tmp/fake ... # Ta-daa!
Using the -I option to add the current folder as an include directory, you could create a folder called "foo" in the current directory and put your libfoo.h file inside.
Obviously, this doesn't strip the "foo" prefix in your #include, but it is a workaround.
I have about 60 extra test files I use for the library. And each has 10 or 20 includes like this. So I can't go through and change #include to #include "./libfoo.h" in 500 or 600 places.
If the above criteria is just a matter of convenience, then a tool like sed can be used to do all the work. Something like
$ sed -i 's/\(^\s*#include\s*[<"]\)foo\/\([^>"]*[>"]\s*$\)/\1\2\t\/\/ This line was replaced/' *
will replace all the occurrences of #include <foo/file.h> with #include <file.h> (you might have to adjust it slightly, I'm on a Windows machine at the moment and can't test it). This will work if all the files are in the PWD. If there is a more complex file structure, then it can be used in conjunction with grep and xargs.
NOTE: Make sure that the svn directories are ignored when using.
Before I get the answer: "Move the code you wish to test to another .cpp file" I cannot do that. I have tried to use preprocessor #if TESTING_SUITE ... #endif but that does not work and I still get the:
multiple definition of `main'
I compile my code like:
g++ -lmxml -lccpunit -o pic pic.cpp wmcc.cp test.cpp
I have one main in pic.cpp and the other in test.cpp. Is there a way around this?
UPDATE
In my test.cpp:
#define TESTING_SUITE_1
In my pic.cpp:
#ifndef TESTING_SUITE_1
int main(...
#endif
Not working
You can specify another entry point to your linker.
For MS cl.exe either in code: (Sorry I didn't see you use gcc)
#pragma comment(linker, "/entry:alternative_main")
or through the project property pages:
Configuration Properties >
Linker >
Advanced >
Entry Point
or directly at the command line:
/entry:alternative_main
For gcc it's the following command line switch:
-Wl,-ealternative_main
For other compilers please refer to the handbook.
You can do it by compiling as
g++ -Dmain=main_pic_moved -c pic.cpp
g++ -Dmain=main_wmcc_moved -c wmcc.cp
g++ -lmxml -lccpunit -o pic pic.o wmcc.o test.cpp
I'm using GCC; __FILE__ returns the current source file's entire path and name: /path/to/file.cpp. Is there a way to get just the file's name file.cpp (without its path) at compile time? Is it possible to do this in a portable way? Can template meta programming be applied to strings?
I am using this in an error logging macro. I really do not want my source's full path making its way into the executable.
If you're using a make program, you should be able to munge the filename beforehand and pass it as a macro to gcc to be used in your program. For example, in your makefile, change the line:
file.o: file.c
gcc -c -o file.o src/file.c
to:
file.o: src/file.c
gcc "-DMYFILE=\"`basename $<`\"" -c -o file.o src/file.c
This will allow you to use MYFILE in your code instead of __FILE__.
The use of basename of the source file $< means you can use it in generalized rules such as .c.o. The following code illustrates how it works. First, a makefile:
mainprog: main.o makefile
gcc -o mainprog main.o
main.o: src/main.c makefile
gcc "-DMYFILE=\"`basename $<`\"" -c -o main.o src/main.c
Then a file in a subdirectory, src/main.c:
#include <stdio.h>
int main (int argc, char *argv[]) {
printf ("file = %s\n", MYFILE);
return 0;
}
Finally, a transcript showing it running:
pax:~$ mainprog
file = main.c
Note the file = line which contains only the base name of the file, not the directory name as well.
I don't know of a direct way. You could use:
#line 1 "filename.c"
at the top of the source file to set the value of __FILE__, but I'm not sure that that's much better than hard coding it. or just using a #define to create your own macro.
Another option might be to pass the name from your Makefile using -D and $(shell basename $<)
Edit: If you use a #define or the -D option, you should create your own new name and not try to redefine __FILE__.
Since you tagged CMake, here's a neat solution to add to your CMakeLists.txt:
(copied from http://www.cmake.org/pipermail/cmake/2011-December/048281.html ). (Note : some compilers don't support per-file COMPILE_DEFINITIONS ! but it works with gcc)
set(SRCS a/a.cpp b/b.cpp c/c.cpp d/d.cpp)
foreach(f IN LISTS SRCS)
get_filename_component(b ${f} NAME)
set_source_files_properties(${f} PROPERTIES
COMPILE_DEFINITIONS "MYSRCNAME=${b}")
endforeach()
add_executable(foo ${SRCS})
Note : For my application I needed to escape the filename string like this:
COMPILE_DEFINITIONS "MYSRCNAME=\"${b}\"")
Consider this simple source code:
#include <stdio.h>
int main(void)
{
puts(__FILE__);
return(0);
}
On Solaris, with GCC 4.3.1, if I compile this using:
gcc -o x x.c && ./x
the output is 'x.c' If I compile it using:
gcc -o x $PWD/x.c && ./x
then __FILE__ maps to the full path ('/work1/jleffler/tmp/x.c'). If I compile it using:
gcc -o x ../tmp/x.c && ./x
then __FILE__ maps to '../tmp/x.c'.
So, basically, __FILE__ is the pathname of the source file. If you build with the name you want to see in the object, all is well.
If that is impossible (for whatever reason), then you will have to get into the fixes suggested by other people.
What does your error logging macro do? I would presume at some point the macro eventually calls a function of some kind in order to do the logging, why not have the called function strip off the path component at runtime?
#define LOG(message) _log(__FILE__, message)
void _log(file, message)
{
#ifndef DEBUG
strippath(file); // in some suitable way
#endif
cerr << "Log: " << file << ": " << message; // or whatever
}
You might be able to do it with template metaprogramming, but there's no built-in way to do it.
EDIT: Hm, correction. According to one page I just saw, GCC uses the path that it's given for the file. If it's given the full name, it'll embed it; if it's only given a relative one, it'll only embed that. I haven't tried it myself though.
Taking the idea from Glomek, it can be automated like this:
Source file x.c
#line 1 MY_FILE_NAME
#include <stdio.h>
int main(void)
{
puts(__FILE__);
return(0);
}
Compilation line (beware the single quotes outside the double quotes):
gcc -DMY_FILE_NAME='"abcd.c"' -o x x.c
The output is 'abcd.c'.
It is easy with cmake.
DefineRelativeFilePaths.cmake
function (cmake_define_relative_file_paths SOURCES)
foreach (SOURCE IN LISTS SOURCES)
file (
RELATIVE_PATH RELATIVE_SOURCE_PATH
${PROJECT_SOURCE_DIR} ${SOURCE}
)
set_source_files_properties (
${SOURCE} PROPERTIES
COMPILE_DEFINITIONS __RELATIVE_FILE_PATH__="${RELATIVE_SOURCE_PATH}"
)
endforeach ()
endfunction ()
Somewhere in CMakeLists.txt
set (SOURCES ${SOURCES}
"${CMAKE_CURRENT_SOURCE_DIR}/common.c"
"${CMAKE_CURRENT_SOURCE_DIR}/main.c"
)
include (DefineRelativeFilePaths)
cmake_define_relative_file_paths ("${SOURCES}")
cmake .. && make clean && make VERBOSE=1
cc ... -D__RELATIVE_FILE_PATH__="src/main.c" ... -c src/main.c
That's it. Now you can make pretty log messages.
#define ..._LOG_HEADER(target) \
fprintf(target, "%s %s:%u - ", __func__, __RELATIVE_FILE_PATH__, __LINE__);
func src/main.c:22 - my error
PS It is better to declear in config.h.in -> config.h
#ifndef __RELATIVE_FILE_PATH__
#define __RELATIVE_FILE_PATH__ __FILE__
#endif
So your linter wan't provide rain of errors.
The question is already 12 years old and back in 2008 this solution wasn't available, but
Starting with GCC 8 and CLANG 10, one can use the option -fmacro-prefix-map.
Acording to GCC Manual:
-fmacro-prefix-map=old=new
When preprocessing files residing in directory ‘old’, expand the
__FILE__ and __BASE_FILE__ macros as if the files resided in
directory ‘new’ instead. This can be used to change an absolute path to
a relative path by using ‘.’ for new which can result in more
reproducible builds that are location independent. This option also
affects __builtin_FILE() during compilation. See also
‘-ffile-prefix-map’.
For instance, the makefile in my IDE (Eclipse) includes the following parameter for GCC for some files: -fmacro-prefix-map="../Sources/"=.
Thus, my debug logs always show only the filenames, without the paths.
Note: GCC 8.1 and Clang 10 were released in May 2018 and March 2020, respectively. So, currently, in September of 2020, only some of my environments support -fmacro-prefix-map.
You can assign __FILE__ to a string, and then call _splitpath() to rip the pieces out of it. This might be a Windows/MSVC-only solution, honestly I don't know.
I know you were looking for a compile-time solution and this is a run-time solution, but I figured since you were using the filename to do (presumably run-time) error logging, this could be a simple straightforward way to get you what you need.
You can take __FILE__ and the strip off the part of path you don't want (programatically). If basedir satisfies your needs, then fine. Otherwise, get source dir root from your build system, and the rest should be doable.
Just got the same issue; found a different resolution, just thought I'd share it:
In a header file included in all my other files:
static char * file_bname = NULL;
#define __STRIPPED_FILE__ (file_bname ?: (file_bname = basename(__FILE__)))
Hope this is useful to someone else as well :)