Closed shaferandrew closed 2 months ago
I think there are two issues, one for nested namespaces on the same line and one for putting the %template
directive in the correct namespace.
Here's a minimal working example:
S_post.mk
TRICK_CXXFLAGS += -Imodels
S_define
#include "sim_objects/default_trick_sys.sm"
##include "trick/SimObject.hh"
##include "Foo.hh"
class Sandbox : public Trick::SimObject {
public:
a::b::c::Foo foo{};
Sandbox() {}
void operator=(const Sandbox&) = delete;
};
Sandbox sandbox;
models/Foo.hh
/**
* @trick_parse{everything}
*/
#ifndef FOO_HH
#define FOO_HH
#include "Bar.hh"
namespace a {
namespace b {
namespace c {
class Foo {
public:
a::Bar<double> bar;
};
}
}
}
#endif
models/Bar.hh
/**
* @trick_parse{everything}
*/
#ifndef BAR_HH
#define BAR_HH
namespace a {
template <class T>
class Bar {
public:
T value{};
};
}
#endif
Running trick-CP:
build/home/ajshafer/dev/SIM_sandbox/models/Foo_py.i:29: Error: 'a::Bar' resolves to 'a::Bar' and was incorrectly instantiated in scope 'a::b' instead of within scope 'a'.
make: *** [build/Makefile_swig:54: build/home/ajshafer/dev/SIM_sandbox/models/Foo_py.cpp] Error 1
Relevant portion of Foo_py.i
(note that the %template
directive should be in namespace a
, not just moved out of Foo
):
namespace a{
namespace b{
#ifndef TRICK_SWIG_TEMPLATE_a__b__c__Foo_bar
#define TRICK_SWIG_TEMPLATE_a__b__c__Foo_bar
%template(a__b__c__Foo_bar) a::Bar<double>;
#endif
namespace c{
class Foo {
public:
a::Bar<double> bar;
#if SWIG_VERSION > 0x040000
%pythoncode %{
__setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)
%}
#endif
};
#define TRICK_SWIG_DEFINED_a__b__c__Foo
}
}
}
To produce the "Extraneous #endif bug", simply collapse Foo.hh's namespaces onto the same line, from:
namespace a {
namespace b {
namespace c {
to:
namespace a { namespace b { namespace c {
Then running trick-CP produces:
build/home/ajshafer/dev/SIM_sandbox/models/Foo_py.i:48: Error: Extraneous #endif.
make: *** [build/Makefile_swig:54: build/home/ajshafer/dev/SIM_sandbox/models/Foo_py.cpp] Error 1
From Foo_py.i (note the #ifndef
needs to be on a new line):
namespace a{ namespace b{ #ifndef TRICK_SWIG_TEMPLATE_a__b__c__Foo_bar
#define TRICK_SWIG_TEMPLATE_a__b__c__Foo_bar
%template(a__b__c__Foo_bar) a::Bar<double>;
#endif
Thanks all the info. Don't believe Trick supports nested namespaces though according to: https://nasa.github.io/trick/documentation/building_a_simulation/Model-Source-Code.html#namespaces Will update the comment if otherwise.
Issue #768 also seems relevant.
The code in #768 doesn't seem to have the stated issue. Able to compile it without any issue with the latest Trick commit.
@hchen99 I was referring to the work here, which placed any qualified types in the global namespace (not just one namespace up). The commit referenced in that comment used a variable in convert_swig
called $global_template_typedefs
, which was placed after all of the class contents, outside of the namespace. In the current version of Trick that variable seems unused now. That work also utilized examples in trick/test/SIM_swig_template_scoping
, but it doesn't look like that sim gets built for testing. I'll see what other examples I can find to better showcase the issue.
Thanks for the info. trick/test/SIM_swig_template_scoping doesn't seem to be in ci process. We'll look into this.
We think this is addressed by PR #1741, closing.
I have tested this against the latest master (e4f6774) and the issue is still present there. It is first introduced by f8a079ec in PR #1679 and is similar to PR #1697. In that issue there is a missing
#endif
but in my issue there is an extraneous#endif
.Attempting to compile many of the subdevices in Trickcat results in the following compilation error:
Looking at the file in question, there is a missing newline before the
#ifndef
macro, causing the preprocessor not to see it:Without this
#ifndef
, later there becomes an "extraneous"#endif
.If I manually insert a newline before the
#ifndef
Trick can proceed but encounters a new issue:The block in question:
If I move the
#ifndef
block out of thepdos
namespace and into thetrickcat
namespace then Trick can finish compiling:If I checkout the last "good" commit (14708ca9), there are no issues present and the block in question looks like this: