Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Papyrus/Codegen/CppHelloWorld"

(Add The Code)
m (Build The Project)
 
(25 intermediate revisions by the same user not shown)
Line 2: Line 2:
 
== Create a C++ Hello World Example ==
 
== Create a C++ Hello World Example ==
  
This walkthrough is a work in progress and as such it is incomplete!!!
+
This walkthrough is now complete but still needs some work to clean it up.
 +
Please post any questions, comments, error or omissions to the Papyrus forum.
 +
 
 +
There is probably too much detail and too many screenshots at the moment.
  
 
== Goals ==
 
== Goals ==
 
Starting from a blank page, create a Papyrus/C++ "Hello World" example, then generate and run the resulting C++ code.
 
Starting from a blank page, create a Papyrus/C++ "Hello World" example, then generate and run the resulting C++ code.
  
The screenshots were created running Eclipse on a Windows 7 machine.
+
The screenshots were created running Eclipse Neon on a Windows 7 machine.
 
Your result will probably look slight different when run on a different OS.
 
Your result will probably look slight different when run on a different OS.
  
 +
If you already have all the required components install, skip ahead to the "Create The Model" section.
  
 
== Prerequisites ==
 
== Prerequisites ==
 
'''1 Eclipse'''
 
'''1 Eclipse'''
 
     Eclipse Neon.3 release 4.6.3 was used to create the example.
 
     Eclipse Neon.3 release 4.6.3 was used to create the example.
 +
    Eclipse Oxygen.1 release 4.7.1 is currently being checked. Differences will be noted in the text.
 +
 
     I started with the Eclipse Modeling Tools packages and added the other components from there.
 
     I started with the Eclipse Modeling Tools packages and added the other components from there.
 
     To check your Eclipse version, select "Help" from the main menu and select "About Eclipse".
 
     To check your Eclipse version, select "Help" from the main menu and select "About Eclipse".
Line 24: Line 30:
 
'''2 Papyrus''' (obviously!)
 
'''2 Papyrus''' (obviously!)
 
     Papyrus version 2.0.3 was used to create this example.
 
     Papyrus version 2.0.3 was used to create this example.
 +
    Papyrus version 3.1.0 is currently being checked.
 +
 
     To check your Papyrus version, select "Help" from the main menu and select "About Eclipse".
 
     To check your Papyrus version, select "Help" from the main menu and select "About Eclipse".
 
     In the resulting popup window, click on the Papyrus icon.
 
     In the resulting popup window, click on the Papyrus icon.
Line 38: Line 46:
 
'''3 A C++ tool chain'''
 
'''3 A C++ tool chain'''
 
     I used the g++ compiler and make in cygwin.
 
     I used the g++ compiler and make in cygwin.
 
+
    I used the GNU g++ compiler version 5.4.0 under ubuntu 16.04.4 to check the Oxygen release.
 +
 
'''4 Eclipse CDT (Optional)'''
 
'''4 Eclipse CDT (Optional)'''
 
     I used version 9.2.1 for these examples.
 
     I used version 9.2.1 for these examples.
 
+
    I used version 9.3.0 to check the Oxygen release.
  
 
== Setup ==
 
== Setup ==
Line 53: Line 62:
 
[[File:OpenPerspective.PNG]]
 
[[File:OpenPerspective.PNG]]
  
Select Papyrus and then click the OK button. Note the new icon.
+
Neon: Select Papyrus and then click the "OK" button. Note the new icon.
 +
 
 +
Oxygen: Select Papyrus and then click the "Open" button. Note the new icon.
  
 
[[File:EclipseMain.PNG]]
 
[[File:EclipseMain.PNG]]
Line 62: Line 73:
  
 
[[File:PapyrusClean.PNG]]
 
[[File:PapyrusClean.PNG]]
 
  
 
== Create The Model ==
 
== Create The Model ==
Line 68: Line 78:
 
'''1. Create the project'''
 
'''1. Create the project'''
  
From the main menu, select File->New->Papyrus Project. The "New Papyrus Project" window pops up.
+
From the main menu, select "File"->"New"->"Papyrus Project". The "New Papyrus Project" window pops up.
  
 
[[File:NewPapyrusProject.PNG]]
 
[[File:NewPapyrusProject.PNG]]
  
Make sure that the UML radio button is selected and then click the "Next >" button.
+
Make sure that the "UML" radio button is selected and then click the "Next >" button.
  
 
[[File:NewPapyrusProject2.PNG]]
 
[[File:NewPapyrusProject2.PNG]]
  
Enter a name for the project, another for the model and leave the default workspace checkbox checked, then click the Finish button.
+
Enter a name for the project, another for the model and leave the default workspace checkbox checked, then click the "Finish" button.
  
The name you entered for the project will be displayed in the Project Explorer window and the name you entered for the model will be displayed if you expand the project.
+
The name you entered for the project will be displayed in the "Project Explorer" area and the name you entered for the model will be displayed if you expand the project.
  
 
As you can see below, I used "myHelloWorldProject" for the project name and "myHelloWorldModel" for the model name. If you would like to exactly recreate the example that comes with Papyrus, use "HellooWorldOO" and "HelloWorld" for the Project and Model names respectively.
 
As you can see below, I used "myHelloWorldProject" for the project name and "myHelloWorldModel" for the model name. If you would like to exactly recreate the example that comes with Papyrus, use "HellooWorldOO" and "HelloWorld" for the Project and Model names respectively.
Line 86: Line 96:
 
'''2. Rename the root element.'''
 
'''2. Rename the root element.'''
  
Select RootElement in the ModelExplorer and notice that the Properties window changes to show the RootElement properties. In the UML tab edit the name to be myHelloWorldRootElement (or HelloWorld to exactly recreate the example).
+
Oxygen: Skip this step. The model aready has the name you gave it in the previous step.
 +
 
 +
Select "RootElement" in the "Model Explorer" area and notice that the "Properties" window changes to show the "RootElement" properties. In the "UML" tab edit the name to be "myHelloWorldRootElement" (or "HelloWorld" to exactly recreate the example).
  
 
[[File:NameRootElement.PNG]]
 
[[File:NameRootElement.PNG]]
Line 92: Line 104:
 
'''3. Create a package.'''
 
'''3. Create a package.'''
  
Right click on the myHelloWorldRootElement, select New Child->Package from the context menu. Name the package myHelloWorldPackage (or classes).
+
Right click on the "myHelloWorldRootElement", select "New Child"->"Package" from the context menu. Name the package "myHelloWorldPackage" (or "classes").
  
 
[[File:NewPapyrusPackage.PNG]]
 
[[File:NewPapyrusPackage.PNG]]
Line 98: Line 110:
 
'''4. Create the class diagram.'''
 
'''4. Create the class diagram.'''
  
Right click on the myHelloWorldPackage in the Model Explorer, select New Diagram->Class Diagram. Name the diagram myHelloWorldClassDiagram (or HelloWorld). Note that a new tab has been created in the main drawing area labelled with the diagram name and that it is empty. Expand the package in the Model Explorer and see that the diagram is a child of the package.
+
Right click on the "myHelloWorldPackage" in the "Model Explorer", select "New Diagram"->"Class Diagram". Name the diagram "myHelloWorldClassDiagram" (or "HelloWorld"). Note that a new tab has been created in the main drawing area labelled with the diagram name and that it is empty. Expand the package in the "Model Explorer" and see that the diagram is a child of the package.
  
 
[[File:PapyrusClassDiagram.PNG]]
 
[[File:PapyrusClassDiagram.PNG]]
Line 104: Line 116:
 
'''5. Add the classes.'''
 
'''5. Add the classes.'''
  
Drag a class from the palette and drop it in the class diagram. It will have a default name of Class1 which will be highlighted. Rename the class to myHelloWorldClass (or HelloWorld). Repeat the process and create a second class and call it myMainClass (or Main). Adjust the positioning and sizing by using the main menu options Diagram->Make Same Size and Diagram->Alignment. Your screen should now look something like this:
+
Drag a class from the "Palette" and drop it in the class diagram. It will have a default name of "Class1" which will be highlighted. Rename the class to "myHelloWorldClass" (or "HelloWorld"). Repeat the process and create a second class and call it "myMainClass" (or "Main"). Adjust the positioning and sizing by using the main menu options "Diagram"->"Make Same Size" and "Diagram->Alignment".  
 +
 
 +
Oxygen: Main menu -> Papyrus -> Diagram -> "Make Same Size".
 +
 
 +
Your screen should now look something like this:
  
 
[[File:HelloWorldClasses.PNG]]
 
[[File:HelloWorldClasses.PNG]]
  
Also note that the classes have been added to the Model Explorer as children of myHelloWorldPackage.
+
Also note that the classes have been added to the "Model Explorer" as children of "myHelloWorldPackage".
  
 
'''5. Add the dependency.'''
 
'''5. Add the dependency.'''
  
Find the Dependecy edge in the palette. Click on the myMainClass class and the drag to other end to the myHelloWorldClass class and click again. You will be prompted to enter a name for the dependency. I left it blank but the example calls it Dependency1. The important thing is to get the direction correct. The arrow head must be pointing to the myHelloWorldClass.
+
Find the "Dependency" edge in the "Palette". Click on the "myMainClass" class and the drag to other end to the "myHelloWorldClass" class and click again. You will be prompted to enter a name for the dependency. I left it blank but the example calls it "Dependency1". The important thing is to get the direction correct. The arrow head must be pointing to the "myHelloWorldClass".
  
 
[[File:HelloWorldDependency.PNG]]
 
[[File:HelloWorldDependency.PNG]]
  
The dependency is added to the Model Explorer as a child of myHelloWorldPackage. If you named it, that name will be displayed but if you didn't it will have the name of the class that depends on the other, ie myHelloWorldClass.
+
The dependency is added to the "Model Explorer" as a child of "myHelloWorldPackage". If you named it, that name will be displayed but if you didn't it will have the name of the class that depends on the other, ie "myHelloWorldClass".
  
 
'''6. (Optional) Add the notes.'''
 
'''6. (Optional) Add the notes.'''
  
The Papyrus HelloWorldOO example contains a few notes which don't affect the code in any way but for the sake of completeness. I'm including the instructions to add them.
+
The Papyrus "HelloWorldOO" example contains a few notes which don't affect the code in any way but for the sake of completeness. I'm including the instructions to add them.
  
Drag a comment from the Palette and drop it to the right of the myHelloWorldClass class. Enter the text as shown below.
+
Drag a comment from the "Palette" and drop it to the right of the "myHelloWorldClass" class. Enter the text as shown below.
  
 
[[File:HelloWorldComment.PNG]]
 
[[File:HelloWorldComment.PNG]]
  
With the new comment selected, note that it is displayed as a child of the myHelloWorldPackage and that the text of the comment is displayed in the Body section of the UML tab in the Properties window.
+
With the new comment selected, note that it is displayed as a child of the "myHelloWorldPackage" and that the text of the comment is displayed in the "Body" section of the "UML" tab in the "Properties" window.
 
Hover your mouse pointer over the comment until the Decorations (official name?) are displayed as shown.
 
Hover your mouse pointer over the comment until the Decorations (official name?) are displayed as shown.
  
 
[[File:NoteDecorations.png]]
 
[[File:NoteDecorations.png]]
  
Move the mouse pointer over the arrow pointing away from the comment, click and drag a line to the myHelloWorldClass class and release to add the association. (Not sure if "association" is the correct term for this link.
+
Move the mouse pointer over the arrow pointing away from the comment, click and drag a line to the "myHelloWorldClass" class and release to add the association. (Not sure if "association" is the correct term for this link.
  
 
[[File:NoteAssociation.PNG]]
 
[[File:NoteAssociation.PNG]]
  
In the Model Explorer select the myHelloWorldPackage and then select the Comments tab in the Properties window. Note that new comment is displayed as an Owned Comment.
+
In the "Model Explorer" select the "myHelloWorldPackage" and then select the "Comments" tab in the "Properties" window. Note that new comment is displayed as an "Owned Comment".
  
 
[[File:OwnedComment.PNG]]
 
[[File:OwnedComment.PNG]]
Line 147: Line 163:
 
'''7. Add the operation.'''
 
'''7. Add the operation.'''
  
Drag an operation from the palette and drop it on the myHelloWorldClass class. It must be dropped either in the class header or in the 2nd compartment otherwise it will not show up. Give it the name run.
+
Drag an "Operation" from the "Palette" and drop it on the "myHelloWorldClass" class. It must be dropped either in the class header or in the 2nd compartment otherwise it will not show up. Give it the name "myHelloWorldOperation" (or "run").
  
 
[[File:RunOperation.PNG]]
 
[[File:RunOperation.PNG]]
  
Note that the operation is displayed in the class diagram and as a child of myHelloWorldClass in the Model Explorer.
+
Note that the operation is displayed in the class diagram and as a child of "myHelloWorldClass" in the "Model Explorer".
  
 
'''8. Optional.'''
 
'''8. Optional.'''
  
The example the comes with Papyrus also has the root element displayed on the class diagram. This is not necessary and in my opinion, clutters the diagram. However, not everyone always agrees with my opinions so if desired, click on the myHelloWorldRootElement in the ModelExplorer and drag it onto the class diagram. Also, if desired, create the comment and associate it with the root element in a similar fashion to before.
+
The example the comes with Papyrus also has the root element displayed on the class diagram. This is not necessary and in my opinion, clutters the diagram. However, not everyone always agrees with my opinions so if desired, click on the "myHelloWorldRootElement" in the "Model Explorer" and drag it onto the class diagram. Also, if desired, create the comment and associate it with the root element in a similar fashion to before.
  
 
== Validate The Model ==
 
== Validate The Model ==
Line 161: Line 177:
 
This step is not strictly necessary but it is a good idea to get in the habit of validating your models, particularly as they get more complicated.
 
This step is not strictly necessary but it is a good idea to get in the habit of validating your models, particularly as they get more complicated.
  
Right click on myHelloWorlRootElement in the Model Explorer to bring up the context menu. Then select Validation -> Validate model.
+
Neon: Right click on "myHelloWorlRootElement" in the "Model Explorer" to bring up the context menu.
 +
 
 +
Oxygen: Right click on "myHelloWorldModel" in the "Model Explorer" to bring up the context menu.
 +
 
 +
Then select "Validation" -> "Validate model".
 +
 
  
 
[[File:ValidateCmd.png]]
 
[[File:ValidateCmd.png]]
  
Check the Model Validation window and check that there are no errors. In case you do not have the Model Validation window open, select Window -> Show View -> Model Validation from the Main menu.
+
Select the "Model Validation" window and check that there are no errors. In case you do not have the "Model Validation" window open, select "Window" -> "Show View" -> "Model Validation" from the main menu.
  
 
[[File:ValidationResults.PNG]]
 
[[File:ValidationResults.PNG]]
Line 174: Line 195:
  
 
We are coding in C++ so the first thing to do is to add the C++ profile.
 
We are coding in C++ so the first thing to do is to add the C++ profile.
Select the myHelloWorldRootElement in the "Model Explorer" and make sure its properties are displayed in the "Property" window.
+
 
Select the "Profile" tab in the "Property" window and then click on the "Apply Registered Profile" icon.
+
Neon: Select the myHelloWorldRootElement  
 +
 
 +
Oxygen: Select the myHellowWorldModel
 +
 
 +
in the "Model Explorer" and make sure its properties are displayed in the "Properties" window.
 +
Select the "Profile" tab in the "Properties" window and then click on the "Apply Registered Profile" icon.
  
 
[[File:AddProfile.PNG]]
 
[[File:AddProfile.PNG]]
Line 195: Line 221:
 
'''2. Write the main() function.'''
 
'''2. Write the main() function.'''
  
In the class diagram, select myMainClass, next the Profile tab in the Properties window and then the Add Stereotype button.
+
In the class diagram, select myMainClass, the "Profile" tab in the "Properties" window and then the "Add Stereotype" button.
  
 
[[File:MainClassProfile.PNG]]
 
[[File:MainClassProfile.PNG]]
  
This pops up and untitled window. Select the Include stereotype from the Applicable Stereotypes window on the left, press the right pointing arrow in the middle to move the stereotype to the Applied Stereotypes window on the right and then click the OK button.
+
This pops up and untitled window. Select the "Include" stereotype from the "Applicable Stereotypes" window on the left, press the right pointing arrow in the middle to move the stereotype to the "Applied Stereotypes" window on the right and then click the "OK" button.
  
 
[[File:ApplicableStereotypes.PNG]]
 
[[File:ApplicableStereotypes.PNG]]
  
The Include stereotype is now added to the Profile window in the Properties tab of the myMainClass properties. Click on the arrow to the left of the stereotype to expand it, then select the body child. Enter the main function code in the window to the right.
+
The "Include" stereotype is now added to the "Profile" window in the "Properties" tab of the myMainClass properties. Click on the arrow to the left of the stereotype to expand it, then select the body child. Enter the main function code in the window to the right.
  
 
[[File:MainFunction.PNG]]
 
[[File:MainFunction.PNG]]
Line 209: Line 235:
 
In the example included with Papyrus, the declaration of the hw object is classes::helloWorld. This is a bug which I have deliberately reproduced as myHelloWorldPackage::myHelloWorldClass. We'll fix this later.
 
In the example included with Papyrus, the declaration of the hw object is classes::helloWorld. This is a bug which I have deliberately reproduced as myHelloWorldPackage::myHelloWorldClass. We'll fix this later.
  
'''3. Write the run() method.'''
+
'''3. Write The myHelloWorldRunMethod (or run()) Method.'''
  
In the Model Explorer, select the run() operation in the mtHelloWorldClass. In the Property view, make sure the UML tab is selected and click the Add Elements button at the top of the Method text box.
+
In the "Model Explorer", select the "myHelloEorldOperation" (or "run()") operation in the myHelloWorldClass. In the "Properties" view, make sure the "UML" tab is selected and click the "Add Elements" button at the top of the "Method" text box.
  
 
[[File:AddMethod.PNG]]
 
[[File:AddMethod.PNG]]
  
This pops up the Method window. Click the "Create new element" button on the right side and select OpaqueBehavior from the context menu.
+
This pops up the "Method" window. Click the "Create new element" button on the right side and select OpaqueBehavior from the context menu.
  
 
[[File:NewMethod.PNG]]
 
[[File:NewMethod.PNG]]
Line 223: Line 249:
 
[[File:NewOpaqueBehavior.PNG]]
 
[[File:NewOpaqueBehavior.PNG]]
  
Now the "Container" window pops up. Expand the root element and the package and select myHelloWorldClass as the container. Click the OK button.
+
Now the "Container" window pops up. Expand the root element and the package and select "myHelloWorldClass" as the container. Click the "OK" button.
  
 
[[File:NewContainer.PNG]]
 
[[File:NewContainer.PNG]]
  
We are now returned to the "Create a new OpaqueBehavior" window and the Container line is filled in with myHelloWorldClass. Now select the "Edit the Reference Value" button on the Reference line:
+
We are now returned to the "Create a new OpaqueBehavior" window and the Container line is filled in with "myHelloWorldClass". Now select the "Edit the Reference Value" button on the "Reference" line:
  
 
[[File:NewOpaqueBehaviour2.PNG]]
 
[[File:NewOpaqueBehaviour2.PNG]]
  
This pops up the "Reference:" window. Select "OwnedBehavior : Behavior" and then click the OK button.
+
This pops up the "Reference:" window. Select "OwnedBehavior : Behavior" and then click the "OK" button.
  
 
[[File:ReferenceWindow.PNG]]
 
[[File:ReferenceWindow.PNG]]
Line 243: Line 269:
 
[[File:NewOpaqueBehavior4.PNG]]
 
[[File:NewOpaqueBehavior4.PNG]]
  
Enter the name of the method, ie "run" in the name line and then click on the Language "Add elements" icon. This pops up the "Language" window.
+
Enter the name of the method, ie "myHelloWorldRunMethod" (or "run") in the name line and then click on the Language "Add elements" icon. This pops up the "Language" window.
  
 
[[File:Language.PNG]]
 
[[File:Language.PNG]]
  
Select "C++" from the left pane, and click the right pointing arrow in the middle to move C++ to the right pane. Click the OK button to return to the previous "Create a new OpaqueBehavior" window.
+
Select "C++" from the left pane, and click the right pointing arrow in the middle to move C++ to the right pane. Click the "OK" button to return to the previous "Create a new OpaqueBehavior" window.
  
 
[[File:NewOpaqueBehavior5.PNG]]
 
[[File:NewOpaqueBehavior5.PNG]]
  
 
Note that the name and language are filled in and that a new text area is displayed to the right of the Language area.
 
Note that the name and language are filled in and that a new text area is displayed to the right of the Language area.
Enter the code as shown. Click on the OK button to return to the "Method" window.
+
Enter the code as shown. Click on the "OK" button to return to the "Method" window.
  
 
[[File:NewMethod2.PNG]]
 
[[File:NewMethod2.PNG]]
  
Note that our new "run" method shows up in the right pane.
+
Note that our new "myHelloWorldRunMethod" (or "run") method shows up in the right pane.
 
Finally, click the "OK" button in the "Method" window.  
 
Finally, click the "OK" button in the "Method" window.  
  
 
[[File:HelloWorldRunMethod.PNG]]
 
[[File:HelloWorldRunMethod.PNG]]
  
The new run method is displayed in the Properties tab Method text area and also in the Model Explorer.
+
The new "myHelloWorldRunMethod" (or "run") method is displayed in the "Properties" tab "Method" text area and also in the "Model Explorer".
 +
 
 +
'''3. Add the #include'''
 +
 
 +
Our "myHelloWorldRunMethod" (or "run") method uses "std::cout" and "std::endl" so we need to add an "#include <iostream>" directive or the code will not compile. There are a couple of places where this can be added but I prefer to see it in the .cpp file where the code is used.
 +
Select the "myHelloWorldClass" (or "HelloWorld") from the "Model Explorer" and then select the "Profile" tab in the "Properties" window. Apply the "Include" stereotype as we did before.
 +
 
 +
[[File:HelloWorldInclude.PNG]]
  
 
== Generate the Code ==
 
== Generate the Code ==
  
Generating the code from the model is very simple. In the Model Explorer, right click on myHelloWorldRootElement to display the context menu. Select Designer -> "Generate C++ Code".  If you dragged the root element onto the class diagram, you can also right click myHelloWorldElement there and get the same context menu.
+
Generating the code from the model is very simple. In the Model Explorer, right click on  
 +
 
 +
Neon: myHelloWorldRootElement  
 +
 
 +
Oxygen: myHelloWorldModel
 +
 
 +
to display the context menu. Select Designer -> "Generate C++ Code".  If you dragged the root element onto the class diagram, you can also right click myHelloWorldElement there and get the same context menu.
  
 
[[File:GenerateHWCode.PNG]]
 
[[File:GenerateHWCode.PNG]]
Line 297: Line 336:
  
 
As I noted earlier, in the "Add The Code" section, there is an error in the main() function. In the screenshot above, note that the code project in the "Project Explorer" window has a small "X" added to the icon. In the screenshot above I have expanded the project and followed the "X" icon down to the myMainClass.cpp file. Then I opened that file and hovered the mouse over the first "X". As you can see the type of the hw class was not able to be resolved.
 
As I noted earlier, in the "Add The Code" section, there is an error in the main() function. In the screenshot above, note that the code project in the "Project Explorer" window has a small "X" added to the icon. In the screenshot above I have expanded the project and followed the "X" icon down to the myMainClass.cpp file. Then I opened that file and hovered the mouse over the first "X". As you can see the type of the hw class was not able to be resolved.
You can also see from the screenshot that the main function is not in any namespace; that is the point but that the myHelloWorldClass is in the myHelloWorldPackage namespace which in turn is in the myHelloWorldRootElement namespace. You can check this by opening up the myHelloWorldClass.h file.
+
You can also see from the screenshot that the main function is not in any namespace; that is the point, but the myHelloWorldClass is in the myHelloWorldPackage namespace which in turn is in the  
  
One solution to our build issue is to fully qualify the hw object. Return to the model, select myMainClass from the class diagram, select the "Profile" tab in the "Properties" window, expand the "Include" and select "body" to display the main() function code. Add "myHelloWorldRootElement::" to the from of the hw declaration. This line is getting tool long for the small code window so display it in the C/C++ view.
+
Neon: myHelloWorldRootElement
 +
 
 +
Oxygen: myHelloWorldModel
 +
 
 +
namespace. You can check this by opening up the myHelloWorldClass.h file.
 +
 
 +
One solution to our build issue is to fully qualify the hw object. Return to the model, select myMainClass from the class diagram, select the "Profile" tab in the "Properties" window, expand the "Include" and select "body" to display the main() function code. Add  
 +
 
 +
Neon: "myHelloWorldRootElement::"  
 +
 
 +
Oxygen: "myHelloWorldModel::"
 +
 
 +
to the from of the hw declaration. This line is getting tool long for the small code window so display it in the C/C++ view.
 
From the main menu, select "Window" -> "Show View" -> "Other..." to display the "Show View" window. Scroll down to the "Papyrus" folder and expand it. Select "C/C++".
 
From the main menu, select "Window" -> "Show View" -> "Other..." to display the "Show View" window. Scroll down to the "Papyrus" folder and expand it. Select "C/C++".
  
Line 308: Line 359:
 
[[File:CCppViewEmpty.PNG]]
 
[[File:CCppViewEmpty.PNG]]
  
Follow the instructions in the window and select the myMainClass class in the class diagram. Now the main code in displayed in the C/C++ view.
+
Follow the instructions in the window and select the myMainClass class in the class diagram. Now the main code in displayed in the "C/C++" view.
  
 
[[File:CppViewMain.PNG]]
 
[[File:CppViewMain.PNG]]
 +
 +
Now save the model and regenerate the code. Check the myHelloWorldClass.cpp file again and check that the red "X"s in the margin are gone. I see that the red "X" in the icons of the "Project Explorer" are still there. TODO: See if this is a known bug.
 +
 +
== Run The Code ==
 +
 +
From the main menu, select "Run" -> "Run Configurations..."
 +
 +
[[File:RunConfigurationsMenu.PNG]]
 +
 +
This pops up the "Run Configurations" window.
 +
 +
[[File:HWRunConfigurations.PNG]]
 +
 +
Expand "C/C++ Application" and select the configuration for our project which is called "Default".
 +
Next we need to specify the name of the executable. The easiest way to to this is to use the "Search Project" button.
 +
Clicking this pops up the "Program Selection" window. Select the binary, there should only be one, and click the "OK" button to close the window and return to the "Run Configurations" window.
 +
 +
[[File:HWProgramSelection.PNG]]
 +
 +
Finally!!! Click the "Run" button in the "Run Configurations" window. "make" will run again, but should have nothing to do, and the results will be displayed in the "Console" view.
 +
 +
[[File:HWRun.PNG]]
 +
 +
== What next? ==

Latest revision as of 13:05, 29 September 2017

Create a C++ Hello World Example

This walkthrough is now complete but still needs some work to clean it up. Please post any questions, comments, error or omissions to the Papyrus forum.

There is probably too much detail and too many screenshots at the moment.

Goals

Starting from a blank page, create a Papyrus/C++ "Hello World" example, then generate and run the resulting C++ code.

The screenshots were created running Eclipse Neon on a Windows 7 machine. Your result will probably look slight different when run on a different OS.

If you already have all the required components install, skip ahead to the "Create The Model" section.

Prerequisites

1 Eclipse

   Eclipse Neon.3 release 4.6.3 was used to create the example.
   Eclipse Oxygen.1 release 4.7.1 is currently being checked. Differences will be noted in the text.
   I started with the Eclipse Modeling Tools packages and added the other components from there.
   To check your Eclipse version, select "Help" from the main menu and select "About Eclipse".

About.PNG

   Q. Is there a minimum version that can be used?
   TODO: Add a link to instructions on installing Eclipse.

2 Papyrus (obviously!)

   Papyrus version 2.0.3 was used to create this example.
   Papyrus version 3.1.0 is currently being checked.
   To check your Papyrus version, select "Help" from the main menu and select "About Eclipse".
   In the resulting popup window, click on the Papyrus icon.

About2.png PapyrusVersion.PNG

   NOTE: An existing hello world example is available via File->New->Example however it is broken in version 2.0.3. 
         This guide was created using a nightly snapshot pending the release of 2.0.4 where the issue should be resolved. See this forum thread for more information: [1]
   Q. Is there a minimum version that can be used?
   TODO: Add a link to instructions on installing Papyrus on the Eclipse.

3 A C++ tool chain

   I used the g++ compiler and make in cygwin.
   I used the GNU g++ compiler version 5.4.0 under ubuntu 16.04.4 to check the Oxygen release.

4 Eclipse CDT (Optional)

   I used version 9.2.1 for these examples.
   I used version 9.3.0 to check the Oxygen release.

Setup

Now everything is installed, start Eclipse. Open the Papyrus perspective. Select Window->Perspective->Open Perspective->Other... from the main menu.

EclipsePerspectiveMenu.PNG

The "Open Perspective" window pops up.

OpenPerspective.PNG

Neon: Select Papyrus and then click the "OK" button. Note the new icon.

Oxygen: Select Papyrus and then click the "Open" button. Note the new icon.

EclipseMain.PNG

Close the Welcome screen to reveal the Papyrus perspective. Make sure that you have the Project Explorer, Model Explorer and Properties windows open.

If not, open them using the main menu Window->Show View.

PapyrusClean.PNG

Create The Model

1. Create the project

From the main menu, select "File"->"New"->"Papyrus Project". The "New Papyrus Project" window pops up.

NewPapyrusProject.PNG

Make sure that the "UML" radio button is selected and then click the "Next >" button.

NewPapyrusProject2.PNG

Enter a name for the project, another for the model and leave the default workspace checkbox checked, then click the "Finish" button.

The name you entered for the project will be displayed in the "Project Explorer" area and the name you entered for the model will be displayed if you expand the project.

As you can see below, I used "myHelloWorldProject" for the project name and "myHelloWorldModel" for the model name. If you would like to exactly recreate the example that comes with Papyrus, use "HellooWorldOO" and "HelloWorld" for the Project and Model names respectively.

EmptyPapyrusModel.PNG

2. Rename the root element.

Oxygen: Skip this step. The model aready has the name you gave it in the previous step.

Select "RootElement" in the "Model Explorer" area and notice that the "Properties" window changes to show the "RootElement" properties. In the "UML" tab edit the name to be "myHelloWorldRootElement" (or "HelloWorld" to exactly recreate the example).

NameRootElement.PNG

3. Create a package.

Right click on the "myHelloWorldRootElement", select "New Child"->"Package" from the context menu. Name the package "myHelloWorldPackage" (or "classes").

NewPapyrusPackage.PNG

4. Create the class diagram.

Right click on the "myHelloWorldPackage" in the "Model Explorer", select "New Diagram"->"Class Diagram". Name the diagram "myHelloWorldClassDiagram" (or "HelloWorld"). Note that a new tab has been created in the main drawing area labelled with the diagram name and that it is empty. Expand the package in the "Model Explorer" and see that the diagram is a child of the package.

PapyrusClassDiagram.PNG

5. Add the classes.

Drag a class from the "Palette" and drop it in the class diagram. It will have a default name of "Class1" which will be highlighted. Rename the class to "myHelloWorldClass" (or "HelloWorld"). Repeat the process and create a second class and call it "myMainClass" (or "Main"). Adjust the positioning and sizing by using the main menu options "Diagram"->"Make Same Size" and "Diagram->Alignment".

Oxygen: Main menu -> Papyrus -> Diagram -> "Make Same Size".

Your screen should now look something like this:

HelloWorldClasses.PNG

Also note that the classes have been added to the "Model Explorer" as children of "myHelloWorldPackage".

5. Add the dependency.

Find the "Dependency" edge in the "Palette". Click on the "myMainClass" class and the drag to other end to the "myHelloWorldClass" class and click again. You will be prompted to enter a name for the dependency. I left it blank but the example calls it "Dependency1". The important thing is to get the direction correct. The arrow head must be pointing to the "myHelloWorldClass".

HelloWorldDependency.PNG

The dependency is added to the "Model Explorer" as a child of "myHelloWorldPackage". If you named it, that name will be displayed but if you didn't it will have the name of the class that depends on the other, ie "myHelloWorldClass".

6. (Optional) Add the notes.

The Papyrus "HelloWorldOO" example contains a few notes which don't affect the code in any way but for the sake of completeness. I'm including the instructions to add them.

Drag a comment from the "Palette" and drop it to the right of the "myHelloWorldClass" class. Enter the text as shown below.

HelloWorldComment.PNG

With the new comment selected, note that it is displayed as a child of the "myHelloWorldPackage" and that the text of the comment is displayed in the "Body" section of the "UML" tab in the "Properties" window. Hover your mouse pointer over the comment until the Decorations (official name?) are displayed as shown.

NoteDecorations.png

Move the mouse pointer over the arrow pointing away from the comment, click and drag a line to the "myHelloWorldClass" class and release to add the association. (Not sure if "association" is the correct term for this link.

NoteAssociation.PNG

In the "Model Explorer" select the "myHelloWorldPackage" and then select the "Comments" tab in the "Properties" window. Note that new comment is displayed as an "Owned Comment".

OwnedComment.PNG

Add the other 2 comments in a similar manner. Your display should now look like this:

AllComments.PNG


7. Add the operation.

Drag an "Operation" from the "Palette" and drop it on the "myHelloWorldClass" class. It must be dropped either in the class header or in the 2nd compartment otherwise it will not show up. Give it the name "myHelloWorldOperation" (or "run").

RunOperation.PNG

Note that the operation is displayed in the class diagram and as a child of "myHelloWorldClass" in the "Model Explorer".

8. Optional.

The example the comes with Papyrus also has the root element displayed on the class diagram. This is not necessary and in my opinion, clutters the diagram. However, not everyone always agrees with my opinions so if desired, click on the "myHelloWorldRootElement" in the "Model Explorer" and drag it onto the class diagram. Also, if desired, create the comment and associate it with the root element in a similar fashion to before.

Validate The Model

This step is not strictly necessary but it is a good idea to get in the habit of validating your models, particularly as they get more complicated.

Neon: Right click on "myHelloWorlRootElement" in the "Model Explorer" to bring up the context menu.

Oxygen: Right click on "myHelloWorldModel" in the "Model Explorer" to bring up the context menu.

Then select "Validation" -> "Validate model".


ValidateCmd.png

Select the "Model Validation" window and check that there are no errors. In case you do not have the "Model Validation" window open, select "Window" -> "Show View" -> "Model Validation" from the main menu.

ValidationResults.PNG

Add The Code

1. Add the C++ profile.

We are coding in C++ so the first thing to do is to add the C++ profile.

Neon: Select the myHelloWorldRootElement

Oxygen: Select the myHellowWorldModel

in the "Model Explorer" and make sure its properties are displayed in the "Properties" window. Select the "Profile" tab in the "Properties" window and then click on the "Apply Registered Profile" icon.

AddProfile.PNG

This pops up the "Apply Profiles" window. Select the "C/C++" profile and then click the "OK" button.

ApplyCppProfile.PNG

Next the "Choose Profile" window pops up. There is only one option, so check the checkbox and click the "OK" button.

ChooseProfile.PNG

The "C_Cpp" profile now appears in the "Profile tab" of the myHelloWorldRootElement.

AddProfileComplete.PNG

Due to the way the code generator handles namespaces, we have to repeat these steps for the myHelloWorldPackage. I have not included the screenshots here but select myHelloWorldPackage in the "Model Explorer" window, select the "Profile" tab in the "Properties" window and repeat the steps to add the "C/C++" profile.

2. Write the main() function.

In the class diagram, select myMainClass, the "Profile" tab in the "Properties" window and then the "Add Stereotype" button.

MainClassProfile.PNG

This pops up and untitled window. Select the "Include" stereotype from the "Applicable Stereotypes" window on the left, press the right pointing arrow in the middle to move the stereotype to the "Applied Stereotypes" window on the right and then click the "OK" button.

ApplicableStereotypes.PNG

The "Include" stereotype is now added to the "Profile" window in the "Properties" tab of the myMainClass properties. Click on the arrow to the left of the stereotype to expand it, then select the body child. Enter the main function code in the window to the right.

MainFunction.PNG

In the example included with Papyrus, the declaration of the hw object is classes::helloWorld. This is a bug which I have deliberately reproduced as myHelloWorldPackage::myHelloWorldClass. We'll fix this later.

3. Write The myHelloWorldRunMethod (or run()) Method.

In the "Model Explorer", select the "myHelloEorldOperation" (or "run()") operation in the myHelloWorldClass. In the "Properties" view, make sure the "UML" tab is selected and click the "Add Elements" button at the top of the "Method" text box.

AddMethod.PNG

This pops up the "Method" window. Click the "Create new element" button on the right side and select OpaqueBehavior from the context menu.

NewMethod.PNG

This pops up the "Create a new OpaqueBehavior" window. Next click on the "Container:" "Edit the Reference Value" button.

NewOpaqueBehavior.PNG

Now the "Container" window pops up. Expand the root element and the package and select "myHelloWorldClass" as the container. Click the "OK" button.

NewContainer.PNG

We are now returned to the "Create a new OpaqueBehavior" window and the Container line is filled in with "myHelloWorldClass". Now select the "Edit the Reference Value" button on the "Reference" line:

NewOpaqueBehaviour2.PNG

This pops up the "Reference:" window. Select "OwnedBehavior : Behavior" and then click the "OK" button.

ReferenceWindow.PNG

Again we are returned to the "Create a new OpaqueBehavior" window and both the "Container:" and "Reference:" lines are filled in.

NewOpaqueBehavior3.PNG

Click the "OK" button. Now a new, different "Create a new OpaqueBehavior" window pops up.

NewOpaqueBehavior4.PNG

Enter the name of the method, ie "myHelloWorldRunMethod" (or "run") in the name line and then click on the Language "Add elements" icon. This pops up the "Language" window.

Language.PNG

Select "C++" from the left pane, and click the right pointing arrow in the middle to move C++ to the right pane. Click the "OK" button to return to the previous "Create a new OpaqueBehavior" window.

NewOpaqueBehavior5.PNG

Note that the name and language are filled in and that a new text area is displayed to the right of the Language area. Enter the code as shown. Click on the "OK" button to return to the "Method" window.

NewMethod2.PNG

Note that our new "myHelloWorldRunMethod" (or "run") method shows up in the right pane. Finally, click the "OK" button in the "Method" window.

HelloWorldRunMethod.PNG

The new "myHelloWorldRunMethod" (or "run") method is displayed in the "Properties" tab "Method" text area and also in the "Model Explorer".

3. Add the #include

Our "myHelloWorldRunMethod" (or "run") method uses "std::cout" and "std::endl" so we need to add an "#include <iostream>" directive or the code will not compile. There are a couple of places where this can be added but I prefer to see it in the .cpp file where the code is used. Select the "myHelloWorldClass" (or "HelloWorld") from the "Model Explorer" and then select the "Profile" tab in the "Properties" window. Apply the "Include" stereotype as we did before.

File:HelloWorldInclude.PNG

Generate the Code

Generating the code from the model is very simple. In the Model Explorer, right click on

Neon: myHelloWorldRootElement

Oxygen: myHelloWorldModel

to display the context menu. Select Designer -> "Generate C++ Code". If you dragged the root element onto the class diagram, you can also right click myHelloWorldElement there and get the same context menu.

GenerateHWCode.PNG

This action pops up a dialog that asks you to confirm the creation of a new Project.

HWCodeProject.PNG

Click on the "Yes" button. Next the create project window is displayed. We are going to use "make" to build the project and the "Cygwin" tool chain to compile it. Expand the "Makefile project" folder in the "Project type:" and select "Empty project". Select an appropriate tool chain from the "Toolchains:" pane. Finally, click the "Finish" button.

HWCodeProject2.PNG

The new project is created an displayed in the "Project Explorer" area. Expand the new project and observe the .h and .cpp files that were created.

HWCodeProject3.PNG

Build The Project

In the "Project Explorer" window, right click on the code project and select "Properties".

HWCodeProjectMenu.PNG

This brings up the project Properties window. The "C/C++ Build" properties should already be selected but if not select them now. Check the "Generate Makefiles Automatically" checkbox in the "Makefile Generation" frame. Click the "OK" button which removes the window.

CppBuildProperties.PNG

From the main menu, select "Project" -> "Build Project". The results of the build are displayed in the "Console" window. If you did not already have a console window open, one will be opened automatically and positioned, by default, to the right of the "Palette" window. In the screen shot below, I have dragged the "Console" window down to the lower area.

HWBuildResultsBad.PNG

As I noted earlier, in the "Add The Code" section, there is an error in the main() function. In the screenshot above, note that the code project in the "Project Explorer" window has a small "X" added to the icon. In the screenshot above I have expanded the project and followed the "X" icon down to the myMainClass.cpp file. Then I opened that file and hovered the mouse over the first "X". As you can see the type of the hw class was not able to be resolved. You can also see from the screenshot that the main function is not in any namespace; that is the point, but the myHelloWorldClass is in the myHelloWorldPackage namespace which in turn is in the

Neon: myHelloWorldRootElement

Oxygen: myHelloWorldModel

namespace. You can check this by opening up the myHelloWorldClass.h file.

One solution to our build issue is to fully qualify the hw object. Return to the model, select myMainClass from the class diagram, select the "Profile" tab in the "Properties" window, expand the "Include" and select "body" to display the main() function code. Add

Neon: "myHelloWorldRootElement::"

Oxygen: "myHelloWorldModel::"

to the from of the hw declaration. This line is getting tool long for the small code window so display it in the C/C++ view. From the main menu, select "Window" -> "Show View" -> "Other..." to display the "Show View" window. Scroll down to the "Papyrus" folder and expand it. Select "C/C++".

ShowViewCpp.PNG

Click the "OK" button and the C/C++ view is displayed.

CCppViewEmpty.PNG

Follow the instructions in the window and select the myMainClass class in the class diagram. Now the main code in displayed in the "C/C++" view.

CppViewMain.PNG

Now save the model and regenerate the code. Check the myHelloWorldClass.cpp file again and check that the red "X"s in the margin are gone. I see that the red "X" in the icons of the "Project Explorer" are still there. TODO: See if this is a known bug.

Run The Code

From the main menu, select "Run" -> "Run Configurations..."

RunConfigurationsMenu.PNG

This pops up the "Run Configurations" window.

HWRunConfigurations.PNG

Expand "C/C++ Application" and select the configuration for our project which is called "Default". Next we need to specify the name of the executable. The easiest way to to this is to use the "Search Project" button. Clicking this pops up the "Program Selection" window. Select the binary, there should only be one, and click the "OK" button to close the window and return to the "Run Configurations" window.

HWProgramSelection.PNG

Finally!!! Click the "Run" button in the "Run Configurations" window. "make" will run again, but should have nothing to do, and the results will be displayed in the "Console" view.

HWRun.PNG

What next?

Back to the top