Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 37

Thread: use #if __has_include - for something like user_defs.h in Arduino sketch?

  1. #1
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,716

    use #if __has_include - for something like user_defs.h in Arduino sketch?

    Sorry for separate thread for this, have eluded to it in a few threads.

    As I have mentioned in the ILI9488_t3 thread, would like to allow the library to compile a couple of different ways, especially for the T4.1

    Right now it can compile differently if you uncomment the line: //#define ENABLE_EXT_DMA_UPDATES // This is only valid for those T4.1 which have external memory.
    in the header file. In which case the frame buffer compiles for 32 bits per pixel in extended memory.

    BUT I can imagine you may not want this for all of your T4.1s.

    So I was thinking about maybe trying to set up a sketch specific include that says, I want that option and hopefully have the library compile see that file was defined and load it and have whatever specific options the user wants for that sketch.

    So I thought I would try: #if __has_include

    First attempt was to define a file as part of the sketch: like user_options.h
    I do a #include of it as part of my sketch and it does not find or use it...

    Code:
    #if __has_include(<user_options.h>)
    #  include <user_options.h>
    #pragma message "ILI9488_t3h - included user_options.h"
    #endif
    Probably because the file gets copied to some other location.

    So then thought maybe add a new header file to the library like:
    Code:
    #if __has_include(<ILI9488_enable_extmem.h>)
    #  include <ILI9488_enable_extmem.h>
    #pragma message "ILI9488_t3h - included ILI9488_enable_extmem.h"
    #endif
    And it always finds it.

    One option that appears to work, is a create a new bogus library with this header file in it.
    In my case I created a directory in the <sketch directory>/libraries/ILI9488_options
    And create the file: ILI9488_enable_extmem.h

    And then in my sketch I added that:
    Code:
    #include "SPI.h"
    #  include <ILI9488_enable_extmem.h>
    #include "ILI9488_t3.h"
    And the compile appears to work with it:
    Code:
    "C:\\arduino-1.8.12\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=152 -DARDUINO=10812 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_4969/pch" "-IC:\\arduino-1.8.12\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\Users\\kurte\\Documents\\Arduino\\libraries\\SPI" "-IC:\\Users\\kurte\\Documents\\Arduino\\libraries\\ILI9488_options" "-IC:\\Users\\kurte\\Documents\\Arduino\\libraries\\ILI9488_t3\\src" "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_4969\\sketch\\Configure_test_graphicstest9488.ino.cpp" -o "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_4969\\sketch\\Configure_test_graphicstest9488.ino.cpp.o"
    In file included from C:\Users\kurte\Documents\Arduino\Teensy Tests\Configure_test_graphicstest9488\Configure_test_graphicstest9488.ino:17:0:
    
    C:\Users\kurte\Documents\Arduino\libraries\ILI9488_t3\src/ILI9488_t3.h:53:17: note: #pragma message: ILI9488_t3h - included user_options.h
    
     #pragma message "ILI9488_t3h - included user_options.h"
    
                     ^
    But was sort of wondering if there is a cleaner way?

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    But was sort of wondering if there is a cleaner way?
    In the TeensyTimerTool I'm using this config.h

    config.h:
    Code:
    #pragma once
    
    #if __has_include("userConfig.h")
        #include "userConfig.h"
    #else
        #include "defaultConfig.h"
    #endif
    If the user wants to override settings he copies the defaultConfig.h into the sketch folder and changes settings as he needs. All library code only includes config.h but depending on file presence it actually gets the information from the default- or the user config.

    Please note: Of course, the sources of already compiled files are not "touched" by generating a userConfig.h. Thus, the build system has no chance to recompile them automatically -> You need to do a clean build once after copying the defaultConfig.h into your sketch directory. After that one-time clean recompile you can change settings in your userConfig as usual. Not a big deal but needs to be explained to your users.
    Last edited by luni; 05-05-2020 at 05:00 AM.

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,571
    @luni - This doesn't seem to work with IDE build - it doesn't seem to include sketch directory in search path - is that part of the build as done there?

    Code:
    T:\arduino-1.8.12\arduino-builder -dump-prefs -logger=machine -hardware T:\arduino-1.8.12\hardware -hardware C:\Users\Tim\AppData\Local\Arduino15\packages -hardware T:\tCode\hardware -tools T:\arduino-1.8.12\tools-builder -tools T:\arduino-1.8.12\hardware\tools\avr -tools C:\Users\Tim\AppData\Local\Arduino15\packages -built-in-libraries T:\arduino-1.8.12\libraries -libraries T:\tCode\libraries -fqbn=teensy:avr:teensy41:usb=serial,speed=600,opt=o2std,keys=en-us -ide-version=10812 -build-path T:\TEMP\arduino_build_769121 -warnings=more -build-cache T:\TEMP\arduino_cache_750735 -verbose T:\tCode\libraries\TeensyTimerTool\examples\HelloOneShot\HelloOneShot.ino
    T:\arduino-1.8.12\arduino-builder -compile -logger=machine -hardware T:\arduino-1.8.12\hardware -hardware C:\Users\Tim\AppData\Local\Arduino15\packages -hardware T:\tCode\hardware -tools T:\arduino-1.8.12\tools-builder -tools T:\arduino-1.8.12\hardware\tools\avr -tools C:\Users\Tim\AppData\Local\Arduino15\packages -built-in-libraries T:\arduino-1.8.12\libraries -libraries T:\tCode\libraries -fqbn=teensy:avr:teensy41:usb=serial,speed=600,opt=o2std,keys=en-us -ide-version=10812 -build-path T:\TEMP\arduino_build_769121 -warnings=more -build-cache T:\TEMP\arduino_cache_750735 -verbose T:\tCode\libraries\TeensyTimerTool\examples\HelloOneShot\HelloOneShot.ino
    Using board 'teensy41' from platform in folder: T:\arduino-1.8.12\hardware\teensy\avr
    Using core 'teensy4' from platform in folder: T:\arduino-1.8.12\hardware\teensy\avr
    Detecting libraries used...
    "T:\\arduino-1.8.12\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=152 -DARDUINO=10812 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IT:\\arduino-1.8.12\\hardware\\teensy\\avr\\cores\\teensy4" "T:\\TEMP\\arduino_build_769121\\sketch\\HelloOneShot.ino.cpp" -o nul
    Alternatives for TeensyTimerTool.h: [TeensyTimerTool@0.1.8]
    ResolveLibrary(TeensyTimerTool.h)
      -> candidates: [TeensyTimerTool@0.1.8]
    "T:\\arduino-1.8.12\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=152 -DARDUINO=10812 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IT:\\arduino-1.8.12\\hardware\\teensy\\avr\\cores\\teensy4" "-IT:\\tCode\\libraries\\TeensyTimerTool\\src" "T:\\TEMP\\arduino_build_769121\\sketch\\HelloOneShot.ino.cpp" -o nul
    Alternatives for defaultConfig.h: []
    ResolveLibrary(defaultConfig.h)
      -> candidates: []
    In file included from T:\tCode\libraries\TeensyTimerTool\src/TeensyTimerTool.h:3:0,
    
                     from T:\tCode\libraries\TeensyTimerTool\examples\HelloOneShot\HelloOneShot.ino:2:
    
    T:\tCode\libraries\TeensyTimerTool\src/config.h:6:31: fatal error: defaultConfig.h: No such file or directory
    
    compilation terminated.
    
    Using library TeensyTimerTool at version 0.1.8 in folder: T:\tCode\libraries\TeensyTimerTool 
    Error compiling for board Teensy 4.1.

  4. #4
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    The errors you get are strange, did you remove the defaultConfig.h? If so, the idea is to copy it, not to move it. (BTW: still need to adjust some defines for the T4.1)

    However, you are right, the Arduino Builder does not include the sketch folder to the search path which renders the pattern useless. When I originally tested the pattern I didn't use if from within a library, then it works of course... What a pitty!

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,571
    Since it won't work either way … pretend I did the right thing

    Actually 'reading' now I see that was not what I did - but I was expecting it to fail … so it worked as expected

  6. #6
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    I know that doesn't help but: the pattern works perfectly with PlatformIO and of course with VisualTeensy. I try to log an issue to ArduinoBuilder maybe they fix that (doubt it...)
    Last edited by luni; 05-05-2020 at 07:10 AM.

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,571
    That would be a cool feature - but since I keep the IDE active to play along with Paul - and then use my editor of choice and TSET to trigger CMDline build with TyComm I find it works for me seamlessly between the two without juggling another thing to learn and maintain for how it is working.

  8. #8
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,571
    Interesting to see if they have a way. It seems I found a simple way ... though looking at boards.txt and platform.txt no other copies or ways to move the file in the same way are apparent.

    For testing I am using : T:\tCode\libraries\TeensyTimerTool\examples\HelloO neShot\HelloOneShot.ino

    { @FrankB , @mjs513, @KurtE, @others? } :: Though TSET has to be used without TyComm for uploading to T_4.1 until it gets a working update - I've been using default IDE and Teensy.exe - it gets the HEX name then requires a button or Ctrl+B in TyComm to cause the upload when it owns the USB_Serial port.

    I added two bold lines ( after green lines ) to my TSET batch file [TSet.cmd2] to copy { to precompile Header where Arduino.h seems to reside } userConfig.h to that folder:
    Code:
    if not exist %temp1% mkdir %temp1%
    if not exist %temp2% mkdir %temp2%
    
    if not exist %temp1%\pch mkdir %temp1%\pch
    if exist userConfig.h copy userConfig.h %temp1%\pch
    Then before with this in defaultConfig.h:
    Code:
    #pragma once
    
    #include "boardDef.h"
    namespace TeensyTimerTool
    {
    xx
    
    //…
    I got an error on the "xx" as expected:
    Code:
    In file included from T:\tCode\libraries\TeensyTimerTool\src/config.h:6:0,
                     from T:\tCode\libraries\TeensyTimerTool\src/TeensyTimerTool.h:3,
                     from T:\tCode\libraries\TeensyTimerTool\examples\HelloOneShot\HelloOneShot.ino:2:
    
    defaultConfig.h:6: error: 'xx' does not name a type
     xx
    With the above edit to Compile.cmd used to build, there was no error. It found and used the PCH\userConfig.h as needed when building the "libraries\TeensyTimerTool" !!!!!

    When I go to the IDE and 'Upload' build it faults still with the above error. Then in the sketch folder if I rename userConfig.h to XuserConfig.h - the error returns as expected.

    So on Windows using TSET this pattern seems to work with a simple edit to TSET building the Compile.cmd file:
    Code:
    #pragma once
    
    #if __has_include("userConfig.h")
        #include "userConfig.h"
    #else
        #include "defaultConfig.h"
    #endif
    Last edited by defragster; 05-05-2020 at 09:24 AM.

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,871
    This sort of user config header has been proposed many times over Arduino's long history. They've consistently rejected it. Maybe this time will be different, but I doubt it.

    Arduino specifically designed their system to not support this sort of external header file config of the libraries. It's not merely an artifact of how they created the include paths. It's a explicit choice towards their design goal of API simplicity.

    FWIW, the other consistent theme is everyone who has proposed this and been rejected hasn't accepted Arduino's rationale behind these decisions. They're used to hearing arguments & rants. It never works. Don't recommend going there when they reject this proposal.

  11. #11
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    Just did a quick prove of principle experiment by adding the path to the build folder
    Code:
    -IC:\\Users\\lutz\\AppData\\Local\\Temp\\arduino_build_422957\\sketch
    to build.flags.common in boards.txt which fixes it for the Arduino IDE (and probably all IDEs relying on the builder -> TSET). Maybe there is a variable for the build path which can be used instead?

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,571
    I could see it as being 'Magic Sauce' - one more file name to learn and use or avoid for the user that doesn't know/want to do prototypes... etc.

    Speaking of Magic - how is the Arduino PRO IDE coming along? Is that a FREE tool also? When I looked at Beta web notes for it I was not sure it wasn't going to be a fee required option?

    As shown above - with FrankB's trigger of the IDE from CMDLine on Windows creation - that creates the TEMP dirs and starts the IDE building - All that was required was make sure %temp%\pch exists and then put the userConfig.h there where I found Arduino.h and it was picked up as needed building the @LUNI LIBRARY.

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,571
    @LUNI - CROSSPOST -

    I SAW (caps lock) this in platform.txt:
    {build.flags.defs} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DF_CPU={build.fcpu} -D{build.usbtype} -DLAYOUT_{build.keylayout} "-I{runtime.platform.path}/cores/{build.core}" "{build.path}/pch/Arduino.h" -o "{build.path}/pch/Arduino.h.gch"
    That showed Arduino.h in :: {build.path}/pch

    But that is moved around 'behind the scenes' with the build tools?

  14. #14
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    That showed Arduino.h in :: {build.path}/pch
    Yay... adding "-I{build.path}/sketch" before {includes} in platform.txt works.

    Code:
    ## Compile c++ files
    recipe.cpp.o.pattern="{compiler.path}{build.toolchain}{build.command.g++}" -c {build.flags.optimize} {build.flags.common} {build.flags.dep} {build.flags.cpp} {build.flags.cpu} {build.flags.defs} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DF_CPU={build.fcpu} -D{build.usbtype} -DLAYOUT_{build.keylayout} "-I{build.path}/pch" "-I{build.path}/sketch" {includes} "{source_file}" -o "{object_file}"

    @Paul: any chance you change platform.txt? :-)

  15. #15
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,899
    ...if that gets added, the "defs.h" could be added, too...

    But I don't see a realistic chance - it would be against Arduino compatibility.
    ..But: Do we need compatibility in this case?

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,871
    Quote Originally Posted by luni View Post
    @Paul: any chance you change platform.txt? :-)
    For 1.52, we're much too close to release to make this sort of build system change which could have unintended consequence.

    Farther in the future, maybe.

    First let's see what Arduino says on that issue. If (when) Arduino rejects it, that's not necessarily the end of story here. But it certainly is something to consider.

  17. #17
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    Thought so.

    I'll leave it in for the time being and see if something strange happens during normal work.

  18. #18
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,155
    @defragster = This is what I get for sleeping and not checking earlier I missed al the fun with this discussion.

  19. #19
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,716
    As I mentioned yesterday, in the first post, I did get it to sort of work, by creating a new logical library, and put the header file __has_include is looking for into that library and then have the sketch include that header file. This will have the Arduino builder find the file and add that directory to the includes list and it worked.

    But wondered if there as a cleaner approach. And yes I know use a different build system

  20. #20
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,155
    @KurtE - not sure there is really a cleaner way to be honest. The has include is the cleanest I think but the IDE seems to be blocking that from what I am reading in the thread without a change to a compile option. As I am typing this I did have a thought - not sure if it would work, but what if in the config.h file in the sketch you have a define for use_config_file that the Lib can see and if its defined then then the config.h can be used or maybe pass it in the begin - just thoughts out loud.

  21. #21
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    IDE seems to be blocking that
    I wouldn't say its blocking it, the builder simply doesn't search in the sketch folder for header files. Therefore, if your library is compiled it doesn't see any user config header located in the sketch so the __has_include will never be true...

    @Kurt: I don't quite understand your pattern. If I want to change some option in your user config I need to do the change in your bogus library right? So what is the advantage over doing the change in the original library in the first place? Or is this meant for exactly one option which I can activate by including the lib or not?

  22. #22
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,716
    @mjs513 - Good Morning,

    I believe Library files unfortunately, do not see anything the sketch defines, so I am not sure it would work...

    For my specific first case I think I may try to leave in the option I added, but also for now add in another __has_include that you mentioned in other thread...
    That of course may not work long term if the extram stuff gets moved into core...

    But I currently have at the start of ILI9488_t3.h file:
    Code:
    #ifndef _ILI9488_t3H_
    #define _ILI9488_t3H_
    #if defined __has_include
    #if __has_include(<extRAM_t4.h>) && defined(ARDUINO_TEENSY41)
    //#include <extRAM_t4.h>
    #define ENABLE_EXT_DMA_UPDATES  // This is only valid for those T4.1 which have external memory. 
    #pragma message "ILI9488_t3h -  extRAM_T4 enabled EXT DMA frame buffer"
    #endif
    
    #if __has_include(<ILI9488_sketch_options.h>)
    #  include <ILI9488_sketch_options.h>
    #pragma message "ILI9488_t3h - included ILI9488_sketch_options.h"
    #endif
    #endif
    And verified that with the sketch that I have the moved the ILI9488_t3 buffer to extended memory the message was printed that told me the option was configured in.

    Without the includes neither of the messages printed. I may issue a PR (minus the messages), as I don't think it will hurt anything and does add the option in that for T4 you could define an external library directory and setup configuration to use 8 bit frame buffer instead of 16 for a specific sketch...

  23. #23
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,716
    @luni - Two things
    a) Wondered if it would work and it did

    b) Original issue - I hate users needing to edit some library for some specific configuration needed for some specific sketch/hardware and then get screwed as it impacted their other projects as well.

    The main thing I was wanting to fix here is for the library I mentioned in previous post and currently can fix the issue by simply detecting if external memory was configured into the sketch or not.

    Thanks

  24. #24
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    901
    Got it thanks.

  25. #25
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,155
    Ditto - got it - too bad. Thanks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •