Skip to content
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

2.0.x dependency spaghetti #8497

Closed
thinkyhead opened this issue Nov 19, 2017 · 22 comments
Closed

2.0.x dependency spaghetti #8497

thinkyhead opened this issue Nov 19, 2017 · 22 comments
Labels
C: Build / Toolchain T: Design Concept Technical ideas about ways and methods. T: Development Makefiles, PlatformIO, Python scripts, etc. T: HAL & APIs Topic related to the HAL and internal APIs.

Comments

@thinkyhead
Copy link
Member

thinkyhead commented Nov 19, 2017

Before going too much further with 2.0.x it seems prudent to work out the interdependency and "hierarchy" of header files. The main issue is that many of the framework, platform, and hardware file headers define their own convenience macros, and many of these are either duplicates of the macros defined for Marlin, or simply use the same name but are defined differently.

I'm not sure how to output a complete "dependency tree", but just doing a search on #include should help to discern the pattern.

Each .cpp file stands alone as its own compilation unit, so each one can include only the headers it needs. Things get a little more complicated when .h files include other .h files. And things get more complicated still when we need to include MarlinConfig.h, since this file attempts to smartly enforce a certain order of header includes, which might not be so smart (mea culpa).

The issue that sparks this post comes from Teensy 3 wiring.h which SPI relies upon.

For reference, here's what `MarlinConfig.h` does…
#include "../core/boards.h"
#include "../core/macros.h"
#include "Version.h"
#include "../HAL/SPI.h"
#include "../../Configuration.h"
#include "Conditionals_LCD.h"
#include "../../Configuration_adv.h"
#include "Conditionals_adv.h"
#include "../HAL/HAL.h"
#include "../pins/pins.h"
#if defined(__AVR__) && !defined(USBCON)
  #define HardwareSerial_h // trick to disable the standard HWserial
#endif
#include "Conditionals_post.h"
#include "SanityCheck.h"

// Include all core headers
#include "../core/enum.h"
#include "../core/language.h"
#include "../core/types.h"
#include "../core/utility.h"
#include "../core/serial.h"

Note that this file includes HAL/SPI.h early, but after boards, macros, and Version — none of which it requires. The first question is, why include HAL/SPI.h here, since so few of Marlin's .cpp files require it? Wouldn't it be better to include it only where needed? Perhaps it's because the Configuration.h files refer to the SPI_XXX_SPEED constants.

The way #define works, this isn't something we need to worry about. As long as the symbols referenced in any #define are defined before the code that uses them, the pre-processor can figure it out.

Consider this example…

test.cpp

#include <iostream>
using namespace std;

#define INC_OUTER THE_OUTER
#define PRE_INCLU INCL_VALU * MY_BEFORE
#include "test.h"
#define MY_BEFORE THE_AFTER
#define THE_AFTER 56

int main(int argc, char const *argv[]) {
  cout << "INC_OUTER=" << INC_OUTER << endl;
  cout << "PRE_INCLU=" << PRE_INCLU << endl;
  cout << "THE_OUTER=" << THE_OUTER << endl; // test.h
  cout << "INCL_VALU=" << INCL_VALU << endl; // test.h
  cout << "MY_BEFORE=" << MY_BEFORE << endl;
  cout << "THE_AFTER=" << THE_AFTER << endl;
  return 0;
}

test.h

#define THE_OUTER THE_AFTER
#define INCL_VALU 666

When you run this code, everything is found, even though some things didn't "exist" before they were referenced by other #define statements.

INC_OUTER=56
PRE_INCLU=37296
THE_OUTER=56
INCL_VALU=666
MY_BEFORE=56
THE_AFTER=56

Keep this in mind when worrying about dependencies. As long as all the referenced symbols are #included, they can be in any order.

So, we don't need to include HAL/SPI.h in MarlinConfig.h for a start. And in a similar manner, pertaining to both .h and .cpp files, we can get rid of #includes where the defined types, methods, etc., are not specifically needed by that file. This will help to prevent name collision. If there are some .cpp files that need to include both wiring.h and macros.h, we should make sure to include macros.h (MarlinConfig.h) only afterward.

There are some good rules of thumb to follow when deciding what to #include and in what order. This post at Stack Overflow is about right…

image

@thinkyhead thinkyhead added T: Design Concept Technical ideas about ways and methods. T: Development Makefiles, PlatformIO, Python scripts, etc. C: Build / Toolchain T: HAL & APIs Topic related to the HAL and internal APIs. labels Nov 19, 2017
@Roxy-3D
Copy link
Member

Roxy-3D commented Nov 19, 2017

There must be tools that generate dependency graphs. And assuming such a tool exists, it probably will tell us how many declarations are in each header file that are needed by the .cpp file.

At: https://stackoverflow.com/questions/42308/tool-to-track-include-dependencies they claim -M -H options on gcc produce a dependency tree.

@thinkyhead
Copy link
Member Author

thinkyhead commented Nov 19, 2017

There must be tools…

Apparently "If you have access to GCC/G++, then the -M option will output the dependency list." but "This only works if there are no errors"

@Roxy-3D
Copy link
Member

Roxy-3D commented Nov 19, 2017

Yeah... and supposedly, -H is a tree format of the -M

More from that page:

For a heavy weight solution, you should check out Doxygen. It scans through your code base and comes up with a website, effectively, that documents your code. One of the many things it shows is include trees.

@thinkyhead
Copy link
Member Author

Aha! Also, Doxygen can make an #include graph (if it can find everything).

@Roxy-3D
Copy link
Member

Roxy-3D commented Nov 19, 2017

Yeah... We are looking at the same web pages! :)

@thinkyhead
Copy link
Member Author

First practical matter to sort out is the sq conflict. Simplest solution is to switch all our code to use square instead of sq. Annoying, but square is probably the more collision-proof macro.

If we wanted to sort it out in terms of header dependencies, then…

The HAL.h header (probably) relies on macros.h (and maybe the configurations). But, it would be better if macros.h were included after wiring.h so that it can override the custom sq macro that the Wiring library uses for its own purposes.

When originally fashioning MarlinConfig.h, the aim was only to ensure that the configurations were all included before including any code that relied on them. It had the side benefit of removing all the #include lines from Configuration.h/Configuration_adv.h. The configurations utilize the macros defined in in macros.h, but as mentioned we can place macros.h anywhere in the include order, so long as it's before any compiled code — that is, before code in a .cpp file and before any .h inline methods.

So, I'm about to stick macros.h at the end of MarlinConfig.h and see how that affects the Teensy sq conflict… here goes nothing…!

@thinkyhead
Copy link
Member Author

Ah… I see that #if also requires things to be defined first. So, backing up a step…

@Roxy-3D
Copy link
Member

Roxy-3D commented Nov 19, 2017

Why is Teensy defining a square macro? Maybe it would make sense to pull that definition out of the file. And if they really do need a square macro, can't they use the standard Marlin one?

(And in that case... macros.h can be very early in the include order where it belongs.)

@thinkyhead
Copy link
Member Author

thinkyhead commented Nov 19, 2017

It's defined by Teensy's own wiring.h header (packages/framework-arduinoteensy/cores/teensy3/wiring.h), so its wiring.* code makes use of it, and then anything else that includes wiring.h can then use it.

The solution is straightforward enough. We just have to make sure to redefine sq for Marlin usage after the Teensy version of Arduino.h has been included. This can be accomplished by redefining it at the end of HAL/HAL.h or at the end of inc/MarlinConfig.h. By our good fortune, both of those files are guaranteed to be included ahead of any of Marlin's own .cpp files, and ahead of any of the .h files that include inline code.

@teemuatlut
Copy link
Member

I actually touched a bit on that sq issue when doing LPC SPI work. I just put an undef directive in HAL_Teensy.h and that was that. The same is done with min() and max() in conditionals_post.h.

That aside, it would definitely be clearer if we could get rid of some of the "collective" header files. Even if that would lead to bigger lists of includes in cpp files.
Maybe one day we can reduce the amount of code defining on header files too.

@thinkyhead
Copy link
Member Author

Even if that would lead to bigger lists of includes in cpp files.

@teemuatlut Totally.

I just put an undef directive in HAL_Teensy.h and that was that.

Yep! I ended up doing the same thing. Except, re-defining it also.

it would definitely be clearer if we could get rid of some of the "collective" header files.

Agreed. The only time we should have an #include in a .h file is when that .h file itself needs something (usually a typedef). If an inline happens to need a header, we might not need the inline.

While tools like Doxygen can tell us what the apparent dependencies are, it can't reveal the real dependencies. For that we'll have to use the compiler. I'm going to try and add the -M flag in my platformio build rules and see if it produces something useful.

@teemuatlut
Copy link
Member

Okey, to clarify there is one place where I think we definitely should have includes within headers and that's the HAL. Basically keep the idea that a Marlin code file will include the HAL file which then further redirects to the proper implementation and information.

@joeedh
Copy link

joeedh commented Nov 19, 2017

For part of one of my first intern jobs in 2007 or 2008 I had to write a python script that generated a dependency graph and plot it with Graphviz. It's not very hard to do this, and I'd recommend whomever is in charge of this sort of refactoring do it themselves.

By the way, for avoiding namespace collisions in macros you might want to look at a system of module prefixes. To keep things from getting too messy, you can have a utility header whose macros are allowed to go prefix-less; everything else must have a module prefix. That way you don't have to deal with the annoyance of spelling out things like MATH_MIN, MATH_FLOOR all the time.

For doing the module prefixes, for an example fastio.h macros could be prefixed with FIO_ or FASTIO_, e.g. FIO_GET_INPUT().

@joeedh
Copy link

joeedh commented Nov 19, 2017

@teemuatlut You can easily end up in a situation where modifying one obscure header forces the whole project to rebuild if you do that. Although I suppose for most people the stupid Arduino build system does that anyway, but eventually you are going to want a proper incremental build.

@teemuatlut
Copy link
Member

That's how the HAL system works at the moment (headers into headers). How would you suggest it should be done for future proofing?
The first alternative that came into my mind would be a HAL object with an interface layer that the different platforms would then have to implement.

@joeedh
Copy link

joeedh commented Nov 20, 2017

Sorry I phrased that wrong. Wasn't supposed to be as assertive as it reads. I prefer to keep my header structure flat, but there's nothing wrong with having a hierarchy of headers so long as you keep the dependency problem in mind. I've done it both ways.

@thinkyhead
Copy link
Member Author

thinkyhead commented Nov 20, 2017

I've applied some preliminary solutions. Most vitally, I split out the first section of inc/MarlinConfig.h into a separate file (inc/MarlinConfigPre.h) that just includes the macros, configs, and conditionals.

#include "../core/boards.h"
#include "../core/macros.h"
#include "Version.h"
#include "../../Configuration.h"
#include "Conditionals_LCD.h"
#include "../../Configuration_adv.h"
#include "Conditionals_adv.h"

This file is safer to include from .h files, as it won't produce any circular includes. I still favor this combined header because it enforces the exact order that configurations and conditionals require. Files that include only this header won't invoke SanityCheck.h, which is fine.

While I'm on the subject of SanityCheck.h, that could be removed from MarlinConfig.h and renamed SanityCheck.cpp so that it will only be invoked one time. Or, it could be included at the bottom of Marlin.ino to ensure it compiles early. That would probably speed up compile times.

I did a compile of the default config for bugfix-2.0.x with the -M and -H flags added to platform.txt and this is the output it generated:

GCC -M -H Output
Generating function prototypes...

. .../hardware/avr/1.6.20/cores/arduino/Arduino.h
.. .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/stdlib.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stddef.h
.. .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stdbool.h
.. .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/string.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stddef.h
.. .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/math.h
.. .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/pgmspace.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/inttypes.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stdint.h
..... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/stdint.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stddef.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/io.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/sfr_defs.h
..... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/inttypes.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/iom2560.h
..... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/iomxx0_1.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/portpins.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/common.h
..... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/sfr_defs.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/version.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/fuse.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/lock.h
.. .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/io.h
.. .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/interrupt.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/io.h
.. .../hardware/avr/1.6.20/cores/arduino/binary.h
.. .../hardware/avr/1.6.20/cores/arduino/WCharacter.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/ctype.h
.. .../hardware/avr/1.6.20/cores/arduino/WString.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/stdlib.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/string.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/ctype.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/pgmspace.h
.. .../hardware/avr/1.6.20/cores/arduino/HardwareSerial.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/inttypes.h
... .../hardware/avr/1.6.20/cores/arduino/Stream.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/inttypes.h
.... .../hardware/avr/1.6.20/cores/arduino/Print.h
..... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/inttypes.h
..... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/stdio.h
...... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/inttypes.h
...... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stdarg.h
...... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stddef.h
..... .../hardware/avr/1.6.20/cores/arduino/WString.h
..... .../hardware/avr/1.6.20/cores/arduino/Printable.h
...... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/stdlib.h
.. .../hardware/avr/1.6.20/cores/arduino/USBAPI.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/inttypes.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/pgmspace.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/eeprom.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/io.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stddef.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/interrupt.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/util/delay.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/inttypes.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/util/delay_basic.h
..... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/inttypes.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/math.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/math.h
... .../hardware/avr/1.6.20/cores/arduino/Arduino.h
.. .../hardware/avr/1.6.20/variants/mega/pins_arduino.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/pgmspace.h
. .../src/inc/MarlinConfig.h
.. .../src/inc/MarlinConfigPre.h
... .../src/inc/../core/boards.h
... .../src/inc/../core/macros.h
... .../src/inc/Version.h
.... .../src/inc/../core/macros.h
... .../src/inc/../../Configuration.h
... .../src/inc/Conditionals_LCD.h
... .../src/inc/../../Configuration_adv.h
... .../src/inc/Conditionals_adv.h
.. .../src/inc/../HAL/HAL.h
... .../src/inc/../HAL/SPI.h
... .../src/inc/../HAL/HAL_AVR/HAL_AVR.h
.... .../hardware/avr/1.6.20/cores/arduino/Arduino.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/util/delay.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/eeprom.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/pgmspace.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/interrupt.h
.... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/io.h
.... .../src/inc/../HAL/HAL_AVR/fastio_AVR.h
..... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/io.h
..... .../src/inc/../HAL/HAL_AVR/../../core/macros.h
..... .../src/inc/../HAL/HAL_AVR/fastio_1280.h
...... .../src/inc/../HAL/HAL_AVR/fastio_AVR.h
.... .../src/inc/../HAL/HAL_AVR/watchdog_AVR.h
..... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/wdt.h
...... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/io.h
.... .../src/inc/../HAL/HAL_AVR/math_AVR.h
.. .../src/inc/../pins/pins.h
... .../src/inc/../pins/../inc/MarlinConfig.h
... .../src/inc/../pins/pins_RAMPS.h
... .../src/inc/../pins/../HAL/HAL_spi_pins.h
.... .../src/inc/../pins/../HAL/HAL_AVR/spi_pins.h
.. .../src/inc/Conditionals_post.h
.. .../src/inc/SanityCheck.h
... .../src/inc/../HAL/HAL_SanityCheck.h
.... .../src/inc/../HAL/HAL_AVR/SanityCheck_AVR_8_bit.h
.. .../src/inc/../core/enum.h
.. .../src/inc/../core/language.h
... .../src/inc/../core/../inc/MarlinConfig.h
... .../src/inc/../core/../lcd/language/language_en.h
... .../src/inc/../core/../lcd/language/language_en.h
.. .../src/inc/../core/types.h
... .../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/string.h
.. .../src/inc/../core/utility.h
... .../src/inc/../core/../inc/MarlinConfig.h
.. .../src/inc/../core/serial.h
... .../src/inc/../core/../inc/MarlinConfig.h
... .../src/inc/../core/../HAL/HAL_AVR/MarlinSerial.h
.... .../src/inc/../core/../HAL/HAL_AVR/../../inc/MarlinConfigPre.h
.... .../hardware/avr/1.6.20/cores/arduino/WString.h

Multiple include guards may be useful for:
.../hardware/avr/1.6.20/cores/arduino/Arduino.h
.../hardware/avr/1.6.20/cores/arduino/HardwareSerial.h
.../hardware/avr/1.6.20/cores/arduino/Print.h
.../hardware/avr/1.6.20/cores/arduino/Printable.h
.../hardware/avr/1.6.20/cores/arduino/Stream.h
.../hardware/avr/1.6.20/cores/arduino/USBAPI.h
.../hardware/avr/1.6.20/cores/arduino/WCharacter.h
.../hardware/avr/1.6.20/cores/arduino/WString.h
.../hardware/avr/1.6.20/cores/arduino/binary.h
.../hardware/avr/1.6.20/variants/mega/pins_arduino.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/common.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/fuse.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/iom2560.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/iomxx0_1.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/lock.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/portpins.h

"ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "/var/folders/9l/_vm2dfnn1w3dgmjfjgnzc8tc0000gn/T/arduino_build_708004/preproc/ctags_target_for_gcc_minus_e.cpp"
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/version.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/avr/wdt.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/stdint.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/stdio.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/include/util/delay_basic.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stdarg.h
.../tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/lib/gcc/avr/4.9.2/include/stdbool.h
.../src/inc/../../Configuration.h
.../src/inc/../../Configuration_adv.h
.../src/inc/../HAL/HAL.h
.../src/inc/../HAL/HAL_AVR/../../core/macros.h
.../src/inc/../HAL/HAL_AVR/HAL_AVR.h
.../src/inc/../HAL/HAL_AVR/SanityCheck_AVR_8_bit.h
.../src/inc/../HAL/HAL_AVR/fastio_1280.h
.../src/inc/../HAL/HAL_AVR/math_AVR.h
.../src/inc/../HAL/HAL_AVR/watchdog_AVR.h
.../src/inc/../HAL/HAL_SanityCheck.h
.../src/inc/../HAL/SPI.h
.../src/inc/../core/../HAL/HAL_AVR/../../inc/MarlinConfigPre.h
.../src/inc/../core/../HAL/HAL_AVR/MarlinSerial.h
.../src/inc/../core/boards.h
.../src/inc/../core/enum.h
.../src/inc/../core/language.h
.../src/inc/../core/serial.h
.../src/inc/../core/types.h
.../src/inc/../core/utility.h
.../src/inc/../pins/../HAL/HAL_AVR/spi_pins.h
.../src/inc/../pins/../HAL/HAL_spi_pins.h
.../src/inc/../pins/pins.h
.../src/inc/../pins/pins_RAMPS.h
.../src/inc/Conditionals_LCD.h
.../src/inc/Conditionals_adv.h
.../src/inc/Conditionals_post.h
.../src/inc/MarlinConfig.h
.../src/inc/MarlinConfigPre.h
.../src/inc/SanityCheck.h
.../src/inc/Version.h

@thinkyhead
Copy link
Member Author

The most straightforward way to figure out dependencies is to start commenting out #include lines and compiling to see what breaks. #if references to undefined symbols are not flagged as errors, so we have to watch out for headers that only use #defines.

Files that rely on config options, whether .h or .cpp, should at least include inc/MarlinConfigPre.h. Many of the files that currently include inc/MarlinConfig.h may now be optimized by including inc/MarlinConfigPre.h instead.

@Phr3d13
Copy link
Contributor

Phr3d13 commented Jun 10, 2019

@thinkyhead Do you still need this open?

@boelle boelle mentioned this issue Jun 22, 2019
20 tasks
@boelle
Copy link
Contributor

boelle commented Jun 22, 2019

@Phr3d13 since they are aiming for a RC it might be time to look at it

@thinkyhead
Copy link
Member Author

Do you still need this open?

Not really. Sorting out the HAL include order is a continuous process and never leaves the TODO list. There are some compiler flags that will produce a report on which files include what, so that will be the primary guide. I would like to standardize the HAL structure and naming conventions too. I think we can trust the compiler to include from the right path, so I don't worry having all files in the HALs share the same names. I'll approach task in tandem with sorting out includes.

@github-actions
Copy link

github-actions bot commented Jul 5, 2020

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Jul 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
C: Build / Toolchain T: Design Concept Technical ideas about ways and methods. T: Development Makefiles, PlatformIO, Python scripts, etc. T: HAL & APIs Topic related to the HAL and internal APIs.
Projects
None yet
Development

No branches or pull requests

6 participants