在编译时获取源文件的基本名称

Imb*_*bue 15 c c++ compiler-construction macros makefile

我正在使用GCC; __FILE__返回当前源文件的完整路径和名称:/path/to/file.cpp.有没有办法file.cpp在编译时获取文件的名称(没有它的路径)?是否可以以便携方式执行此操作?模板元编程可以应用于字符串吗?

我在错误记录宏中使用它.我真的不希望我的源代码完整路径进入可执行文件.

pax*_*blo 12

如果你正在使用make程序,你应该能够事先处理文件名并将其作为宏传递给你的程序中使用的gcc.

在makefile中,更改行:

file.o: file.c
    gcc -c -o file.o src/file.c
Run Code Online (Sandbox Code Playgroud)

至:

file.o: src/file.c
    gcc "-D__MYFILE__=\"`basename $<`\"" -c -o file.o src/file.c
Run Code Online (Sandbox Code Playgroud)

这将允许您__MYFILE__在代码中使用而不是__FILE__.

使用源文件的基名($ <)意味着您可以在通用规则中使用它,例如".co".

以下代码说明了它的工作原理.

文件makefile:

mainprog: main.o makefile
    gcc -o mainprog main.o

main.o: src/main.c makefile
    gcc "-D__MYFILE__=\"`basename $<`\"" -c -o main.o src/main.c
Run Code Online (Sandbox Code Playgroud)

文件src/main.c:

#include <stdio.h>

int main (int argc, char *argv[]) {
    printf ("file = %s\n", __MYFILE__);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

从shell运行:

pax@pax-desktop:~$ mainprog
file = main.c
pax@pax-desktop:~$
Run Code Online (Sandbox Code Playgroud)

注意"file ="行只包含文件的基名,而不是dirname.

  • 请注意,以双下划线(或下划线和大写字母)开头的名称是为实现保留的。最好避免使用`__MYFILE__`,可能使用`MYFILE` 或类似的东西。 (2认同)

And*_*isi 6

我不知道有什么直接的方法。你可以使用:

#line 1 "filename.c"
Run Code Online (Sandbox Code Playgroud)

在源文件的顶部设置 的值__FILE__,但我不确定这是否比硬编码好得多。或者只是使用 #define 来创建您自己的宏。

另一种选择可能是使用 -D 和 $(shell basename $<) 从 Makefile 传递名称

编辑:如果您使用 #define 或 -D 选项,您应该创建自己的新名称,而不是尝试重新定义__FILE__


Jon*_*ler 5

考虑这个简单的源代码:

#include <stdio.h>
int main(void)
{
    puts(__FILE__);
    return(0);
}
Run Code Online (Sandbox Code Playgroud)

在Solaris上,使用GCC 4.3.1,如果我使用以下命令编译它:

gcc -o x x.c && ./x
Run Code Online (Sandbox Code Playgroud)

输出是' x.c'如果我使用以下方法编译它:

gcc -o x $PWD/x.c && ./x
Run Code Online (Sandbox Code Playgroud)

然后__FILE__映射到完整路径(' /work1/jleffler/tmp/x.c').如果我用以下方法编译它:

gcc -o x ../tmp/x.c && ./x
Run Code Online (Sandbox Code Playgroud)

然后__FILE__映射到' ../tmp/x.c'.

所以,基本上,__ FILE__是源文件的路径名.如果使用要在对象中看到的名称构建,一切都很好.

如果这是不可能的(无论出于何种原因),那么你将不得不进入其他人建议的修复.


fen*_*rec 5

由于您标记了 CMake,这里有一个简洁的解决方案可以添加到您的 CMakeLists.txt 中:(从http://www.cmake.org/pipermail/cmake/2011-December/048281.html复制)。(注意:有些编译器不支持每个文件的 COMPILE_DEFINITIONS !但它适用于 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})
Run Code Online (Sandbox Code Playgroud)

注意:对于我的应用程序,我需要像这样转义文件名字符串:

COMPILE_DEFINITIONS "MYSRCNAME=\"${b}\"")
Run Code Online (Sandbox Code Playgroud)