PlatformIO Community

__FILE__ always returns src/main.cpp (Arduino ESP8266)

If I use Arduino IDE and Serial.println(__FILE__) I get the full pathname.

If I use platformio I get src/main.cpp.

AFAIK the first is the correct behaviour – and the second is pointless.

Am I missing something?

I’ve edited your post and made the underscores appear again. And I’ve removed the exclamation at the end of the post.

Underscores are an alternative markup for italics and bold. Use the </> button or backticks to format code.

There seems to be no standard mandating the full path. The gcc documentation says:

This is the path by which the preprocessor opened the file, …

And the PIO build system calls the compiler with a relative path, namelu src/main.cpp. See the last line in the below example (line breaks added):

-o .pio/build/d1_mini_lite/src/main.cpp.o
-c -fno-rtti -std=c++11 -Os -mlongcalls -mtext-section-literals -falign-functions=4
-U__STRICT_ANSI__ -ffunction-sections -fdata-sections -fno-exceptions -Wall
-Iinclude -Isrc

The Arduino build process is different. Since .ino sketches are not valid C++ code, they need to be pre-processed. Part of the pre-processing is to manipulate file and line information.

The processed source files looks like this before it is passed to the compiler:

#line 1 "/Users/me/Documents/Arduino/example/example.ino"
#include <Arduino.h>

#line 3 "/Users/me/Documents/Arduino/example/example.ino"
void setup();
#line 9 "/Users/me/Documents/Arduino/example/example.ino"
void loop();
#line 3 "/Users/me/Documents/Arduino/example/example.ino"
void setup() {

void loop() {

The #line directive affects the __FILE__ macro. Therefore, it’s not surprising that it will result in the full pathname.

1 Like

That may all be true but the fact is FILE is useful in arduino and not so in platformio.

Can you elaborate a bit here? Why is the full path better than the relative path as seen from src/?

Why would FILE exist?

I like to include it and TIME and DATE as print statements in the first lines of my program so iIcan see what is actually within the ESP8266 or whatever.

I guess other people find similar uses for FILE

To put it another way what is the point of a magic macro which always returns src/main.ccp?

It doesn’t always return src/main.cpp unless the file is always called that.

  Serial.print("Sensor Hub v");
  Serial.println(" init!");
  Serial.print("Compile Date / Time : ");
  Serial.print(" / ");
  Serial.print("Filename : ");

Gave as the output …

Sensor Hub v0.2.0 init!
Compile Date / Time : Sep 25 2019 / 08:25:23
Filename : src\sensor_hub.cpp

… because my application’s main source file is not named main.cpp… hence it gives the name of the source file as the macro pre-processor saw it.

Well that is interesting. All the docs I have seen say “it creates a file called main.cpp” and never mention that it can be renamed. Since AFAIK Arduino always creates something called main I supoosed this carried over to platformio.

However I generally organise using folders - which are inherently uniquely named - and I’d rather not have to manually ensure that my file also has a unique name.

As far as I know, there’s no requirement that the main entrypoint of your program be called main.cpp… however, it’s more of a convention that file containing that main entrypoint… main() … is called main.cpp just so you can find it. Arduino do it differently… they require the main sketch file to have the same name as the folder containing it. But there is unfortunately nothing requiring either the __FILE__ or __BASE_FILE__ macros to contain absolute paths…

The Microsoft C++ compiler has a flag that lets you change the behaviour between relative and absolute paths… but I don’t anything similar for the GNU C++ compiler. -fmacro-prefix-map=old=new is the nearest I get, but it seems that you’re have to hard-code the path… just like if you used the #line directive in the source file to set the name/line number.


Thank you all for the information.

I shall continue (remembering to) enter the pathname as a litteral - and escaping as required.

And I guess that is where it ends.

1 Like