Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__FILE__ macro manipulation handling at compile time

One of the issues I have had in porting some stuff from Solaris to Linux is that the Solaris compiler expands the macro __FILE__ during preprocessing to the file name (e.g. MyFile.cpp) whereas gcc on Linux expandeds out to the full path (e.g. /home/user/MyFile.cpp). This can be reasonably easily resolved using basename() but....if you're using it a lot, then all those calls to basename() have got to add up, right?

Here's the question. Is there a way using templates and static metaprogramming, to run basename() or similar at compile time? Since __FILE__ is constant and known at compile time this might make it easier. What do you think? Can it be done?

like image 356
ScaryAardvark Avatar asked Sep 11 '25 04:09

ScaryAardvark


1 Answers

In projects using CMake to drive the build process, you can use a macro like this to implement a portable version that works on any compiler or platform. Though personally I pity the fool who must use something other than gcc... :)

# Helper function to add preprocesor definition of FILE_BASENAME
# to pass the filename without directory path for debugging use.
#
# Note that in header files this is not consistent with
# __FILE__ and __LINE__ since FILE_BASENAME will be the
# compilation unit source file name (.c/.cpp).
#
# Example:
#
#   define_file_basename_for_sources(my_target)
#
# Will add -DFILE_BASENAME="filename" for each source file depended on
# by my_target, where filename is the name of the file.
#
function(define_file_basename_for_sources targetname)
    get_target_property(source_files "${targetname}" SOURCES)
    foreach(sourcefile ${source_files})
        # Add the FILE_BASENAME=filename compile definition to the list.
        get_filename_component(basename "${sourcefile}" NAME)
        # Set the updated compile definitions on the source file.
        set_property(
            SOURCE "${sourcefile}" APPEND
            PROPERTY COMPILE_DEFINITIONS "FILE_BASENAME=\"${basename}\"")
    endforeach()
endfunction()

Then to use the macro, just call it with the name of the CMake target:

define_file_basename_for_sources(myapplication)
like image 59
Colin D Bennett Avatar answered Sep 12 '25 17:09

Colin D Bennett