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"

(Goals)
m (Goals)
Line 13: Line 13:
 
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 "Build The Model" section.
+
If you already have all the required components install, skip ahead to the "Create The Model" section.
  
 
== Prerequisites ==
 
== Prerequisites ==

Revision as of 12:35, 23 May 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 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.
   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.
   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.

4 Eclipse CDT (Optional)

   I used version 9.2.1 for these examples.


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

Select Papyrus and then click the OK 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 window 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.

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).

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. 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 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.

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 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 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.

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.

Right click on myHelloWorlRootElement in the Model Explorer to bring up the context menu. Then select Validation -> Validate model.

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.

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. Select the myHelloWorldRootElement 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, next 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 run() Method.

In the "Model Explorer", select the "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 "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 "run" method shows up in the right pane. Finally, click the "OK" button in the "Method" window.

HelloWorldRunMethod.PNG

The new run method is displayed in the Properties tab Method text area and also in the Model Explorer.

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.

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 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.

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. 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