如何提取,而不在编译时的路径和后缀源文件名? [英] How to extract the source filename without path and suffix at compile time?

查看:247
本文介绍了如何提取,而不在编译时的路径和后缀源文件名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

同时使用GCC与-std = C11和g ++与-std = C ++ 14。

Using both gcc with -std=c11 and g++ with -std=c++14.

例如。对于一个名为的src / DIR / Hello.cxx 应该扩大到像例如:

E.g. for a file named src/dir/Hello.cxx it should expand to something like e.g.:

const char basename[] = "Hello";

const char basename[] = getStaticBasename(__FILE__);

作为其中 getStaticBasename()是宏(碳源)或constexpr功能(C ++源代码),这将导致为Hello。

as where getStaticBasename() is a macro (for C sources) or constexpr function (for C++ sources) which results to "Hello".

我必须避免分裂从字符串__ FILE __ 在运行时,由于路径和后缀不能被编译成以任何方式可执行文件。

I have to avoid splitting the string from __FILE__ at runtime, because the path and suffix must not be compiled into the executable in any way.

解决方案必须依赖没有巨大的图书馆,如升压。

The solution must be without dependencies to huge libraries such as boost.

由于我没有makefile文件,如解决这个不能在我的情况下使用。

As I have no makefiles, solutions like this cannot be used in my case.

做了一有解决的办法是什么?

Did one have a solution for that?

编辑2015年7月2日:

Edit 2015-07-02:


  • 我有命令行编译器和链接是如何被调用(有时通过生成文件没有影响,有时候,还是有些IDE(Eclipse CDT的管理时许,CrossWorks的,X code等等。因此,解决方案需要在code只。

  • 我的用例是为小尺寸记录解决方案提供了某种通用区域标识的。该应用程序code(使用我的记录器)应该只的#include<乔/ Logger.h> 和后面调用例如内 LOG_DEBUG(...)我会拿隐含使用自动生成的非专利区域标识的。

  • 我目前的解决方案是应用code必须声明一个 JOE_LOG_FILE_REGION(你好); (后的#include<乔/ Logger.h> ),然后才能把 LOG_DEBUG(...)在code

  • I have no influence on how the compiler and linker was invoked (sometimes via makefile, sometimes from command line, or some IDE (Eclipse CDT managed make, Crossworks, Xcode et cetera. So the solution needs to be in code only.
  • My use case is to provide some kind of "generic region identifier" for a small footprint logging solution. The application code (which uses my logger) should only #include <Joe/Logger.h> and within the later calls to e.g. LOG_DEBUG(...) I'll implicitely take use of the automatically generated "generic region identifier".
  • My current solution is that the application code have to declare a JOE_LOG_FILE_REGION(Hello); (after #include <Joe/Logger.h>) before it could place LOG_DEBUG(...) in its code.

推荐答案

如果你所在的源文件所在的文件夹运行gcc,你会得到一个不同的 __ FILE __ 比如果你传递一个绝对路径(即递交通过IDE到GCC)。

If you run gcc from the folder where the source file is located, you will get a different __FILE__ than if you pass an absolute path (i.e. handed to gcc through an IDE).


  • GCC test.c的-otest.exe 给我 __ __ FILE test.c的

  • 的gcc C:\\ tmp目录\\ test.c的-otest.exe 给我 __ __ FILE C:\\ tmp目录\\ test.c的

  • gcc test.c -otest.exe gives me __FILE__ as test.c.
  • gcc c:\tmp\test.c -otest.exe gives me __FILE__ as c:\tmp\test.c.

也许调用gcc被其中源所在的路径就足够变通?

Perhaps calling gcc from the path where the source is located is sufficient as work-around?

修改

下面是一个脏,但安全黑客从而消除在编译时的文件扩展名。真的不是我建议,但它是有趣的写:)所以把它的东西很值得。它仅适用于温度。

Here is a "dirty" but safe hack which removes the file extension in compile-time. Not really something I'd recommend, but it was fun to write :) So take it for what it is worth. It only works in C.

#include <stdio.h>

#define EXT_LENGTH (sizeof(".c") - 1) // -1 null term

typedef union
{
  char filename_no_nul [sizeof(__FILE__)-EXT_LENGTH-1]; // -1 null term
  char filename_nul    [sizeof(__FILE__)-EXT_LENGTH];
} remove_ext_t;

int main (void)
{
  const remove_ext_t file = { __FILE__ };

  puts(file.filename_nul);

  return 0;
}

工会分配一个成员是大到足以容纳完整路径减去延伸和空终止符。它分配一个成员是大到足以容纳完整路径减去扩展,虽然是一个空终止符。

The union allocates one member which is large enough to hold the full path minus extension and null terminator. And it allocates one member which is large enough to hold the full path minus extension, though with a null terminator.

这是太小,无法容纳全部成员 __ FILE __ 与尽可能多的的__ FILE __初始化为能适应。这是在C确定,但在C ++中不允许的。如果 __ FILE __ 包含 test.c以,工会成员现在将初始化为包含测试无空终止。

The member which is too small to hold the full __FILE__ is initialized with as much of __FILE__ as can fit. This is ok in C but not allowed in C++. If __FILE__ contains test.c, the union member will now be initialized to contain test with no null terminator.

有但是仍然会是字符串后面尾随零,因为这个黑客滥用的事实,其他联合成员已按照总量/联盟初始化规则被初始化。此规则将强制在聚合任何剩余的物品,如果他们有静态存储时间,即到零初始化。这恰好是空终止的价值。

There will however still be trailing zeroes after that string, because this hack abuses the fact that the other union member has been initialized according to the rules of "aggregate/union" initialization. This rule forces any remaining items in the "aggregate" to be initialized as if they had static storage duration, i.e to zero. Which happens to be the value of the null terminator.

这篇关于如何提取,而不在编译时的路径和后缀源文件名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆