I would like to do conditional compiling and include different C files based on the hardware being used. For example:
#ifdef HARDWARE_MODULE_1
#include "hardware_module_1.c"
#endif
#ifdef HARDWARE_MODULE_2
#include "hardware_module_2.c"
...
Everything works fine this way only debugging becomes a problem. Breakpoints don't work correctly when placed in the C file that's included that way. The program ends up breaking somewhere else random in the code (different C file altogether) When I manually add file to the project everything seems to be working fine. I'm using uVision V4.60.6.10
"Neither does it make the opposite statement."
Irrelevant. A bug is when the software functionality breaches the contract. What isn't part of the contract can't be a bug - but is quite likely a bad assumption.
If the car manufacturer promises the car can do 200 km/h, then it must be able to do that. But it doesn't tell if the car can do 220 km/h or not.
"Besides, Including C file into another C file is legal from the language standpoint."
The world is full of constructs that are legal from the language standpoint. The language allows you to write code that does division by zero - but the outcome of running the code will most probably not be a big success.
In your specific case, the compiler do produce a working program. It's just that you assume that you should also be able to have breakpoints in the included files. And a breakpoint in "hardware_1.c" would normally have the debug information in "hardware_1.o", but you never produced any "hardware_1.o"...
"There is nothing wrong with producing a single compilation unit from several source files."
That depends on your assumptions of the outcome, outside of the contract of the compiler being able to produce working programs.
The preprocessor will merge all #include into a single file that the compiler will process. But the line numbers in this merged file can't be used while debugging, since the debugger will not be able to open such a merged file.
So the preprocessor might then decide to not just insert line numbers, but also file names in the merged data to allow the debugger to not just map to different lines in the source file, but to map to lines in the different included files. But the thing here is that you need to separate what is required by the language, and what is implementation decisions when implementing the compiler, the debug format and the debugger.
"For all your pontification and colorful albeit misapplied metaphors you failed to give a factual reason for what exactly goes wrong when you include .c file."
Not actually true - you just decided to brush aside what I wrote.
Just as you can get a car with 2 doors or 5 doors, different compilers will have different functionality - there are a lot of things that aren't locked down by the language standard. Compilers that also supports C++ are much more likely to support breakpoints in header files since it's part of the C++ concept to have implementation code in header files.
Here is, by the way, a link to an older version of gcc that couldn't handle breakpoints in header files because the debug information could not handle more than one source file name per object file: www.delorie.com/.../faq12_6.html
That just about "all" C++ compilers supports breakpoints in header files doesn't mean you can expect all C compilers to do it. Since a C++ compiler needs to handle code in header files, a C++ compiler would use a debug format that supports it. And would use the same debug format when compiling C code.
The problem here is that most compilers you ever see something written about on the net are C/C++ compilers, i.e. capable of supporting both languages. So people makes assumptions based on only having seen luxury implementations. For many years, a huge number of people constantly reported bugs all over the net whenever a C compiler couldn't handle // end-of-line comments. Just because they assumed it was part of the C language standard since a very large number of compilers did add that functionality as a non-standard extension when compiling C.
"There is also another advantage in my approach. Other tools (or IDE's) will compile the project correctly."
The same thing would be true if each individual C file is separately compiled but with all code inside an #if/#endif block, and either assumes that you either have a global define in the project file/Makefile or a single header file that specifies the defined symbol. And then you would get debugging to work with all compilers that supports the generation of debug information.