2

I'm having a project which compiles perfectly with gcc, but fails to compile under Greenhills Integrity environment.

The problem boils down to this three files:

MyVector.cpp // contains function testVector
MyVector.hpp // contains template vector<>
SomeFile.cpp

MyVector.hpp contains template-class for a vector, and MyVector.cpp contains a testing function unrelated to MyVector.hpp's templates.

Now, when I'm using MyVector.hpp's vector templates in SomeFile.cpp, somehow, the function testVector gets injected into SomeFile.cpp. When I cease to use vector in SomeFile.cpp (I'm still #include'ing it of course, I'm just not instantiate the template there) it works perfectly.

Moreover when I injected a warning into function testVector, the compiler showed the warning when I compiled SomeFile.cpp!

Moreover, the build system recompiles SomeFile.cpp when I'm changing things in MyVector.cpp.

When I'm deleting the testVector function from MyVector.cpp and move it to a new NewFile.cpp - it compiles.

No, I didn't include the cpp file by mistake, honest, I double checked it, and greped all my source code.

I have no idea what's going on. I'll be glad for any clue.

Charles
  • 50,943
  • 13
  • 104
  • 142
Elazar Leibovich
  • 32,750
  • 33
  • 122
  • 169

3 Answers3

2

Green Hills uses the Edison Design Group front-end, and until very recently (say, MULTI 5.0 or maybe even 5.2) the compiler turned on --implicit_include by default. Here's the Edison documentation for that option:

--implicit_include
--no_implicit_include
-B
     Enable or disable implicit inclusion of source files as a method of
     finding definitions of template entities to be instantiated. -B is
     equivalent to --implicit_include. The default behavior is specified
     by the configuration flag DEFAULT_IMPLICIT_TEMPLATE_INCLUSION_MODE.
     See the section of this chapter on template instantiation. This
     option is valid only in C++ mode.

Your problem will very likely be fixed if you pass --no_implicit_include on the compiler command line. (If that fails, try -W0,--no_implicit_include or :compiler.args=--no_implicit_include, either of which will pass the option straight through to the front-end without (much) censorship by the driver. Passing --std or --STD might also help; I don't remember.)

Implicit inclusion is a terribly stupid idea today, but it was a convenient way to provide template functionality back in the '90s. Today, there are standard and well-known ways of satisfying the One Definition Rule, and this "implicit inclusion" hack just gets in the way of law-abiding C++tizens such as yourself.

Now go on, ask me about prelinking... :)

Quuxplusone
  • 23,928
  • 8
  • 94
  • 159
-1

When you say you 'inject a warning' are you using a #pragma directive? A #pragma directive is meant to be seen during compile time, not during run time.

When you say the function 'testVector gets injected into SomeFile.cpp', how is this observed? Do you get a compiler or linker error saying that the function was previously defined?

Are you compiling gcc for Integrity OS or gcc for x86 Linux?
Integrity works very differently from Linux, and the type of Integrity project matters. You can build a monolithic Integrity kernel or an Integrity kernel supporting dynamic download. Additionally the Integrity C and C++ runtime libraries are different from Linux.

this.josh
  • 663
  • 9
  • 21
  • When I said "inject a warning" to file A, I meant that I deliberated wrote code in file A that cause the compiler to issue a warning. It caused warning to an unrelated file B. What you wrote about `#pragma` is true, but I don't see any relation not to the question neither to the answer. When I said a function from file A get injected to file B, I mean that errors in file A are shown when compiling file B, even though they're unrelated. If you'll look at the title you can see I'm compiling *with* Integrity's GCC. – Elazar Leibovich Apr 13 '11 at 05:07
  • I wrote about #pragma because I was speculating that (#pragma) was how you were generating the warning. I was unaware that Integrity had a GCC compiler. I thought that Green Hills only produced the Multi tool set (IDE, compiler, debugger). I thought you were compiling with the GNU Compiler Collection GCC as a sanity check. Are you saying that you can compile with a Green Hills compiler for a Linux target with success but when you compile with a Green Hills compiler for Integrity, it fails? – this.josh Apr 13 '11 at 22:03
  • No. When I'm compiling the program with GCC for linux it succeeds. When I'm compiling the program with the Multi toolset (it's variation of gcc, it's linker etc), it fails. I'm not sure that Integrity is using GNU `gcc`, but it doesn't really matter. BTW, I didn't use #pragma to generate the warning, but it's a perfectly good method of doing that, and completely irrelevant to the question. – Elazar Leibovich Apr 14 '11 at 08:57
  • The Green Hills Multi tool set does not use GCC, its compilers are cxlnxppc (C++ for PowerPC architectures), cclnxppc (C for PowerPC). Compiling with GCC for x86 Linux is different from compiling with Multi for a non-x86 Integrity target. The compiler matters, the architecture matters, and the operating system matters. Compilers parse differently, they issue different warnings and errors, they have different bugs. Operating systems targets use different sets of include files and different libraries for linking. – this.josh Apr 14 '11 at 21:29
  • Different architectures produce different assembly and different binaries. There is a difference even in compiling with different versions of gcc for the same architecture and operating system targets. To solve this problem it is helpful to know the host architecture, host OS, host compiler, target architecture, and target OS. It seems that you are compiling A) x86 Linux GCC to ARM?(a guess) Integrity and B) x86 Linux Multi to ARM?(a guess) Integrity To understand why A works and B does not, I need to know the difference between A and B. – this.josh Apr 14 '11 at 21:36
  • @this.josh, you guessed correctly about the targets, but your assumption that the compiler is invoked correctly is flawed. As I wrote, there are a very fundamental bug with the Multi build process. Even before generating code to the specific architecture. – Elazar Leibovich Jun 09 '11 at 13:50
-2

How are you implementing vector? I'm thinking you're implementing this in MyVector.cpp and including MyVector.cpp at the end of MyVector.hpp. If this is the case, including MyVector.hpp in SomeFile.cpp will trigger a rebuild of SomeFile.cpp when you change MyVector.cpp. I'd suggest run it through the pre-processor and see where the testVector() is being included from.

Tareq A. Siraj
  • 424
  • 3
  • 9
  • -1. I'm quoting myself "No, I didn't include the `cpp` file by mistake, honest... I double checked it." It is implemented as a regular template in the `h` file only. In the `MyVector.cpp` file there's only a single 'testVector` function, that's it. Please read the question more carefully. I added a paragraph exactly to prevent such simplistic answer. Also please note the code compiles with `g++`. – Elazar Leibovich Sep 16 '10 at 07:14
  • Yes I did. But even if I didn't the fact that changing the file name solves the problem should imply that this is not related to the preprocessor. – Elazar Leibovich Nov 02 '10 at 20:17