Book a Demo

Author Topic: C++ include files section  (Read 9424 times)

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
C++ include files section
« on: April 23, 2013, 09:53:21 am »
I am transforming a PIM to a C++ PSM. My PIM->C++ model transform creates a class and adds attributes to it using the Attributes {} blocks. I generate C++ code from the transformed model. The C++ files generated from the C++ code gen template do not have the corresponding header include statements. If I create the same class and attributes manually, the generated C++ does have include statements (corresponding to namespace/namespace/.../classname.h).

What do I need to place into the model transform to trigger the code gen to add the include statements?

Thanks,
Dan

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #1 on: April 23, 2013, 03:47:46 pm »
I see that the type="blah::foo" attribute assignment statement doesn't resolve the same way as if I use the dialog to set attribute type. After my transform, the dialog shows the fully qualified type. If I override it by browsing to blah::foo, which I created with the model transform, the dialog shows only "foo." Generating code after the override correctly generates the include file section.

I tried moving the template statements that create the new classes ahead of the ones adding the class attributes typed by the new classes. Didn't make any difference. Still no include file statements.

Example:
Code: [Select]
Package
{
  name="blah"
Class
{
  name="foo"
}
Class
{
  name="bar"
Attribute
{
  name="aFoo"
  type="blah::foo"
}
}
}

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8110
  • Karma: +119/-20
    • View Profile
Re: C++ include files section
« Reply #2 on: April 24, 2013, 08:28:48 am »
Include statements are generated if the classifier is pointing to a class external to the current file. Just setting the type name in the transform doesn't set the classifier.

You can use the TRANSFORM_CLASSIFIER macro to do this. (Also search for that for a little more information in the help.)

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #3 on: April 24, 2013, 11:11:49 am »
Thank you, Simon, that worked.

For others, the Class I created needed to have a TRANSFORM_REFERENCE("<unique name>") in it. The Attribute needed to have a TRANSFORM_CLASSIFIER("<name given to transform reference>").

I'm cross compiling to Linux. How do I get the path name separators to lean the right direction?

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #4 on: April 24, 2013, 11:23:42 am »
Code: [Select]
$imports=%fileImports%
$sl=%sl%
%REPLACE($imports, $sl, "/")%

Of course.

Thx.

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #5 on: April 25, 2013, 03:26:24 am »
Now I want to make the path separator conditional so I can generate for Windows or Linux w/o changing the template. ImportSection is invoked at file scope so I'm not sure how to mark the input model.

How do I put a tag into the M2M transform such that the value is accessible in the C++ transform?

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #6 on: April 25, 2013, 10:01:51 am »
I want to reference types that are imported from source code. The documentation says I can use the existing GUIDs in the classifier assignment. The referenced type name can be constructed in the transform but I have no way to construct the GUID.

Any ideas?

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #7 on: April 25, 2013, 10:12:39 am »
Example:
Attribute
{
  name="foo"
  type=%qt%Root::%packageName%::%className%Suffix%qt%
}

The imported code has type names that fit the pattern.

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8110
  • Karma: +119/-20
    • View Profile
Re: C++ include files section
« Reply #8 on: April 26, 2013, 09:07:06 am »
Setting the type by name will never set the classifier.

If you have in your source model an attribute that is already the appropriate type then you can use the following.

Code: [Select]
Attribute
{
  name=%qt%%attName%%qt%
  classifier=%qt%%attClassifierGUID%%qt%
}

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #9 on: April 28, 2013, 05:39:28 am »
The attClassifierGUID is an empty string. I don't know how it would resolve to the desired GUID w/o some indication of what that type is. Here is the resulting intermediate file after adding the attClassifierGUID macro.
Code: [Select]
Attribute
{
  name="FooDataWriter"
  type="GV::Baz::dds::FooDataWriter_var"
  scope="private"
  classifier=""
}

I was able to generate code using a stereotype and tag:
Code: [Select]
 stereotype="dcps"
Tag
{
    name="typeName"
    value=%qt%%className%%qt%
}
Which gives this intermediate:
Code: [Select]
 ...
  stereotype="dcps"
Tag
{
    name="typeName"
    value="Foo"
}

I'm relatively satisfied with this approach.

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #10 on: May 11, 2013, 04:15:29 pm »
I went ahead and created an add-in function that can find a fully qualified type name in the model and return the GUID. Now I can use classifier=%qt%%EXEC_ADD_IN(...)%%qt% to cleanly trigger include statements.

The next problem is to get headers for types that are neither attribute types, operation return/parameter types, nor associations. For example, using a global singleton or using constants or enumerations.

Creating a fake association will do it for types but it is misleading. I also suspect that associations don't actually cause headers to be included; it appears to be the attribute created to hold the reference that triggers the include statement. Ticking the code gen options box to omit attributes for associations makes the include statements go away. That might explain why Dependency didn't do the trick.

I tried header="blah.h" and import="blah.h" but no luck. I plan to use a tag but would rather use a built-in construct if there is one.

Any ideas?

Thanks,
Dan

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #11 on: May 13, 2013, 05:59:44 am »
The syntax for header and import intermediary attributes is the same as C++. The strings must be valid include statements or the C++ code generator ignores them.

e.g.,
Code: [Select]
Class
{
  name="foo"
  header="#include <iostream>#include \"SACCP/ccpp_dds_dcps.h\""
}
The code generator properly parses this and outputs each statement on a new line.

Cheers,
Dan

DanG83616

  • EA User
  • **
  • Posts: 180
  • Karma: +0/-0
    • View Profile
Re: C++ include files section
« Reply #12 on: May 14, 2013, 03:52:13 am »
I created dependency relationships between classes and the types known to be referenced but not as attribute types. Recall that the C++ code generator only inserts include statements for attribute types or association relationships (which end up as attributes). I added Connector__DependencyInclude custom code gen template to generate the statements. Two problems:

1. It involves a GUID->GenFile look-up add-in function that initially takes 10 seconds to cache the Dictionary (and whenever a look-up fails).  :(
2. I cannot seem to get the statements wedged between the %headerFiles% and the using statement in the impl file.

Achievable but unacceptable:
Code: [Select]
#include "ThisClass.h" // From code generator
#include <iostream> // From header= intermediary

using ThisClass;

#include "Dependency.h" // From my dependency template
...
Undesirable but achievable:
Code: [Select]
#include "Dependency.h" // From my dependency template
#include "ThisClass.h" // From code generator
#include <iostream> // From header= intermediary

using ThisClass;
...
Desired:
Code: [Select]
#include "ThisClass.h" // From code generator
#include "Dependency.h" // From my dependency template
#include <iostream> // From header= intermediary

using ThisClass;
...
Acceptable:
Code: [Select]
#include "ThisClass.h" // From code generator
#include <iostream> // From header= intermediary
#include "Dependency.h" // From my dependency template

using ThisClass;
...

I'm thinking the dependency approach was not a good idea. Instead, I should be adding the files to the header="" intermediate in the model transform template. I'll still have the look-up problem, though.

I hope documenting my follies helps others avoid them. Of course, I'm open to good advice to avoid them...

Cheers,
Dan