nasa / trick

Trick Simulation Environment. Trick provides a common set of simulation capabilities and utilities to build simulations automatically.
Other
34 stars 19 forks source link

Compile error with C++ headers using "*.h" suffix #711

Open excaliburtb opened 5 years ago

excaliburtb commented 5 years ago

There may be 2 issues here.

  1. ICG/clang produces error messages about needing c++ linkage for .h headers with c++ constructs.
  2. The script/code that produces the S_source.hh file placing all .h header files within an extern "C" {} block.

The first problem may be ugly but doesn't necessarily kill the sim compilation. For the second problem, we just need a way to test if the header is C or c++. We could execute a compile test with the test .h file against C, if it fails, then do not place the header in the extern "C" block.

dbankieris commented 5 years ago

I think the assumption that a .h extension indicates C code is made in several places in Trick. I suspect @alexlin0 will be reluctant to change that.

excaliburtb commented 5 years ago

The assumption for the the .h extension isn't a good one for external headers which is the use case I am concerned with. @alexlin0 is pretty reasonable, I don't care what you say behind his back.

alexlin0 commented 5 years ago

I remember that we do have a mechanism to deal with this. In the Trick comment you can specify the language. It was put in for this exact case where c++ headers end in .h.

/*
PURPOSE: (code)
LANGUAGE: (c++)
*/
excaliburtb commented 5 years ago

Yes, that is an option if one is able to modify the header. I think we can take it one step further though.

diff --git a/libexec/trick/pm/parse_s_define.pm b/libexec/trick/pm/parse_s_define.pm
index 8c2dfe9..4395378 100644
--- a/libexec/trick/pm/parse_s_define.pm
+++ b/libexec/trick/pm/parse_s_define.pm
@@ -894,7 +894,34 @@ sub handle_compiler_directive($$) {
                     $suffix = "cpp" ;
                 }
                 else {
-                    $suffix = "c" ;
+                    open tmp_fh, ">test_language.h" or return;
+                    print tmp_fh "#include \"", $file_name, "\"\n";
+                    print tmp_fh "int main() { return 0; }\n";
+                    close(tmp_fh);
+                    my $cc_cmd = 'cc -c test_language.h';
+                    my $cxx_cmd = "c++ -c test_language.h";
+                    my $comp_cmd = '';
+                    foreach(@{$$sim_ref{inc_paths}}) {
+                       (my $path = $_) =~ s/\\//g ;
+                       $comp_cmd = "$comp_cmd -I$path";
+                    }
+                    $comp_cmd = "$comp_cmd -o test_language.h.out > /dev/null 2>&1";
+                    $cc_cmd = "$cc_cmd $comp_cmd";
+                    $cxx_cmd = "$cxx_cmd $comp_cmd";
+                    my $ret = `$cc_cmd`;
+                    if($? != 0) {
+                       $ret = `$cxx_cmd`;
+                       if($? == 0) {
+                          trick_print($$sim_ref{fh}, "INFO: Detected $file_name as a C++ header with a *.h extension.\n", "normal_yellow", $$sim_ref{args}{v});
+                          $suffix = "cpp" ;
+                       } else {
+                          $suffix = "c" ;
+                       }
+                    } else {
+                       $suffix = "c" ;
+                    }
+                    unlink "test_language.h";
+                    unlink "test_language.h.out";
                 }
             } else {
                 $suffix = "cpp" ;

Of course, the concern would be, will it slow down the perl parsing of the S_define too much? Just something to think about I guess. I think I can run with this for our purposes because I know our system is relatively small.

alexlin0 commented 5 years ago

If you cannot modify the header files, then I would prefer a command line argument to trick-CP specifying the language of particular files instead of testing each one. Perhaps something like this.

TRICK_CPFLAGS += --langc++=<path_to_file>
dbankieris commented 5 years ago

I generally prefer automatic solutions, as the less the user has to do, the better! But this might be a case where the rarity doesn't justify the expense.

Also, gcc's man page shows that it infers the language from the extension as well and provides the -x option when you need to be explicit.

excaliburtb commented 5 years ago

gcc language determination doesn't apply well to header detection that I know of. It does to source files.

I can understand the argument to keep this out of standard CP. However, I could have a significant number of header files with this problem. So, if it isn't part of the standard CP processing, I would like to be able to run CP over the S_define and create my list of --langc++= entries for me. In other words, give me a tool for automatic detection so that I can use the TRICK_CPFLAGS option. The perl modules still seem like the most appropriate place for this optional behavior.

Or add a TRICK_CPFLAGS switch that enables this behavior.