-
-
Notifications
You must be signed in to change notification settings - Fork 808
Use of #ifdef not processed consistently #2972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
|
Fixed in 4ee4315 and a separate branch. Let's wait when all tested will passed. |
That's quick! |
Yes, we try to keep PIO Core in the bugs-free state as much as we can. |
That's a noble pursuit :) |
@ivankravets thank you for fast action! |
@uzi18 Nope, not yet. |
@TD-er just be sure where platfomio is installed, this should be easy with virtualenv |
Sorry, but we don't have good news here. The issue was labeled with We recommend using CPP instead of INO for advanced cases, like this. I did some progress in this branch https://github.com/platformio/platformio-core/tree/feature/issue-2972-ino2cpp but a few tests failed. So, switching to full output from GCC Pre-Processor makes more problems for us because all "includes" are expanded. See updated solutions for this issue here #2972 (comment) |
Thanks for the update. Do you think it is possible to add an easy detection at least? |
@TD-er what about option on top of file header to disable prototypes auto prepending? |
@uzi18 The problem is mainly caused by using #ifdef statements for .ino files. |
but with this feature you can add proper prototypes in file manually inside #ifdefs just add eg. #pragma platformio-proto-disable I'm curious if our libs are also affected here |
@uzi18 libraries are not affected because they are true C/C++ The problem only with INO sketch which has specific logic under ifdef guards. This is the first case for the last 5 years :) |
OK, this converting to .h/.cpp from .ino (combined with bad programming style of various programmers) is opening a number of boxes formally owned by someone named Pandora. For example, in order to not be forced to modify +/- 200 files, I want to keep some stuff "global", like our settings. Well let's define one outside the scope of a class or struct in a .h file. #ifndef BLA_DIE_BLA_H
#define
struct bla {
...
};
bla _global_bla;
#endif // BLA_DIE_BLA_H Include this blaDieBla.h from more than one location and then the compiler does not want to link because it does see multiple instances of this I know it isn't the best practice in programming, but as an intermediate solution would be fine to have those global variables present. Probably because of the time of day, but right now I really don't understand why the linker does see multiple instances of the same variables, since the .h file should be parsed only once. This all started just to be able to exclude some parts of the code in some builds since we're hitting the max. sketch size on almost all builds :(
|
PlatformIO INO->CPP converter adds only prototypes declarations for those which do not have them. So, if you add declaration under #ifdef it will work. |
Thanks for the reply. I already found out what was happening. "global" variables in a .h file will indeed lead to multiple declarations from where they are included. So last night's reply was kind of a frustration caused by a PEBKAC :) (and lack of sleep by then) |
Great! We plan to start soon work on new LDF. It's a plan to have |
That's something I also firmly believe in :) |
This is not entirely what I'm seeing here. This macro is only called from within #ifdef statements, but still is forward declaration appears in the generated .ino.cpp file without the #ifdef wrapping statements and even worse, it also appears when the defines are not set. The macro: #define DEFINE_Cxxx_DELAY_QUEUE_MACRO(NNN, M) \
bool do_process_c##NNN####M##_delay_queue(int controller_number, \
const C##NNN####M##_queue_element & element, \
ControllerSettingsStruct & ControllerSettings); \
ControllerDelayHandlerStruct<C##NNN####M##_queue_element>C##NNN####M##_DelayHandler; \
void process_c##NNN####M##_delay_queue(); \
void process_c##NNN####M##_delay_queue() { \
C##NNN####M##_queue_element *element(C##NNN####M##_DelayHandler.getNext()); \
if (element == NULL) return; \
MakeControllerSettings (ControllerSettings); \
LoadControllerSettings(element->controller_idx, ControllerSettings); \
C##NNN####M##_DelayHandler.configureControllerSettings(ControllerSettings); \
if (!WiFiConnected(10)) { \
scheduleNextDelayQueue(TIMER_C##NNN####M##_DELAY_QUEUE, C##NNN####M##_DelayHandler.getNextScheduleTime()); \
return; \
} \
START_TIMER; \
C##NNN####M##_DelayHandler.markProcessed(do_process_c##NNN####M##_delay_queue(M, *element, ControllerSettings)); \
STOP_TIMER(C##NNN####M##_DELAY_QUEUE); \
scheduleNextDelayQueue(TIMER_C##NNN####M##_DELAY_QUEUE, C##NNN####M##_DelayHandler.getNextScheduleTime()); \
} And how it is called from within a .h file: #ifdef USES_C015
DEFINE_Cxxx_DELAY_QUEUE_MACRO(0, 15)
#endif // ifdef USES_C015 It will add the first line in the macro in the generated .ino.cpp file, but the class it refers as a parameter does not exist in the code since it is also wrapped in the same #ifdef Could it be this macro is preprocessed regardless the #ifdef wrapping it? I also tried declaring this macro in the .ino file actually using it, but then another function defined in the macro ( So I do seem to be in a catch-22 here, or I must strip a lot of this from the macro in order to be able to remove these objects from the built binary. |
As a work-around I now do all the forward declarations of the function with the templated class as argument, in the ino file instead of the macro. It does look like this (in the .ino file) bool do_process_c018_delay_queue(int controller_number, const C018_queue_element& element, ControllerSettingsStruct& ControllerSettings);
bool do_process_c018_delay_queue(int controller_number, const C018_queue_element& element, ControllerSettingsStruct& ControllerSettings) {
bool success = C018_data.txHexBytes(element.packed, ControllerSettings.Port);
return success;
} This allows me to have these templated objects all in the #ifdef wrappers. |
Sorry for the delay and this issue. I'm going to close it. People think that we will fix it soon. To be honest, we don't plan to rewrite our INO to the CPP converter. I did a more detailed answer here #3706 So, let's be transparent with our community. There are 2 solutions:
We don't see any sense to invest in INO when no one supports it. It breaks all IDEs because they don't do this crazy converting on-the-fly for each INO file when doing parsing. |
Solutions
1. Convert INO files to CPP
2. Manual prototype declaration
PlatformIO Core.
As discussed here: esp8266/Arduino#6475
Configuration
Operating system:
Windows & Linux
PlatformIO Version (
platformio --version
):PlatformIO, version 4.0.3
Description of problem
When generating forward declarations of functions in the .ino.cpp, the wrapping #ifdef statements are not taken into account.
Steps to Reproduce
Simple steps to reproduce: esp8266/Arduino#6475 (comment)
Not really a very simple project at hand here, but I guess this should be enough to have in the project.ino file.
Just use the https://github.com/esp8266/Arduino/blob/74819a763bfb6e9890a57411dcea4aba221a778d/libraries/esp8266/examples/Blink/Blink.ino
and add some function like this in the .ino file:
As long as you don't have the
DO_NOT_USE
flag set, you should not see it in the generated .ino.cpp file. (it should be wrapped in the #ifdef statements)Well at least, that's what I expect should happen.
Things will fail to build if you have some object used as parameter which is only defined when a flag is set. For example:
The text was updated successfully, but these errors were encountered: