Introduction
Starting with the 20.01 Azure Sphere release, Visual Studio projects will no longer be supported by the Azure Sphere SDK. I have a few Azure Sphere projects that are still using Visual Studio project files that I'm currently porting to CMake. I thought I would share my porting process.
High Level Overview
There are a few things we need to port the project to CMake . . .
- Convert our project to use the hardware abstractions (if not already being used)
- Add CMake specific files
- Open our project as a CMake project
- Update the CMake files with details for our project
- Build and test our project
- Remove the solution *.sln file(s) from our project
Convert the project to use the hardware abstraction layer
Most of my older projects originated from Microsoft examples that were created before they implemented the hardware abstraction files for the GitHub example applications. I understand why this layer was created, but personally I was happy defining my hardware interfaces with constants and values. Microsoft does document how to create a project without using the hardware abstraction files (look under item #5), but I found that the instructions did not work for me. I've submitted feedback on my issues, but to move forward I've decided to go ahead and add the hardware abstraction layer to my project.
Note: If you're project is already using the hardware abstraction layer, then you can skip this section.
My recommendation is to add the hardware abstraction layer to the Visual Studio Solution before starting the CMake port. This way, you'll have confidence that your hardware abstraction port is working correctly before moving on. I guarantee that we'll see CMake errors when we do the CMake port; eliminating hardware abstraction changes first will make life easier.
Include the Hardware specific files in your project
- If you don't already have the Microsoft examples, clone the Microsoft Azure Sphere GitHub Project.
- Copy the Hardware directory to your project directory
- You can choose to include a common Hardware directory in your directory structure. I like to include this directory inside my project directories. I share my projects and it's easier to share when I package all the required files together.
- I add my Hardware directory to the same folder where all my source files are located. You're free to add the Hardware directory anywhere you wish.
- You can also clean up the Hardware directory if you don't plan on supporting all the different Azure Sphere Boards/Modules. For example, I'm using the Avnet Azure Sphere Starter Kit, so I only include the directories that I need.
Update the Visual Studio Project
Next we need to tell Visual Studio about the Hardware directory.
- Open your Visual Studio project in Visual Studio
- Use the shortcut keys <ALT> + <Enter> to bring up the project properties page
- Fill in the "Target Hardware Definition Directory" and "Target Hardware Definition" fields
- I'm using the Avnet Azure Sphere Starter Kit so I specify that folder and definition file
- If you placed your Hardware directory somewhere else in your file system you need to adjust the path to reference the location of your directory
- If you're using a different hardware platform, then specify the folder and Hardware Definition file for your platform
- While you're in this dialog make a note of the "Target API Set."
- Actually screen shot this window, we'll need this detail for our CMake project
Update your app_manifest.json file
When you use the Hardware Abstraction layer, you can no longer use constants in your app_manifest.json file.
- Using the *.h file from your <Target Hardware Definition Directory>/inc/hw/ folder, find the #define for each resource you reference in the app_manifest.json file. Add the string identifier to the app_manifest.json file with quotes and a '$' like this: "$<my identifier here>"
For example: My app_manifest.json file included a 9 for the GPIO to drive the Green LED on the on-board RGB LED
I used the definitions found in avnet_mt3620_sk.h:
And updated my app_manifest.json file as shown below:
Once you update all the constants in your app_manifest.json file you should be able to build and run your Visual Studio project.
Add CMake specific files
We need to add three different CMake files to our project. My recommendation is to pull the current Microsoft Azure Sphere GitHub Project as a starting point.
- Clone the Microsoft Azure Sphere GitHub Project
- Open the <project folder>/Samples/AzureIoT folder
Open our project as a CMake project
Next we'll open the project as a CMake project. This will allow us to make changes and test the build as we go.
- Close your Visual Studio Project
- Launch Visual Studio
- From the pull down menus File --> Open --> CMake...
- Navigate to your project file and select the CMakeLists.txt file you just copied there
- The project will open and CMake will try to generate the build script. It will fail as shown below. Don't worry about that, this is expected and will happen until we get the CMake files tuned up
Note: Anytime you want to regenerate the CMake project, just change and save your CMakeLists.txt file. I just add a space somewhere and save.
Update the CMake files with details for our project
Now it's time to get into the details . . .
Edit CmakeLists.txt
- From inside Visual Studio, open the CMakeLists.txt file
- Update the ADD_EXECUTABLE(${PROJECT_NAME} line
- Find all the *.c files in your project and list them on this line
- Use " " spaces between the file names
- Update the TARGET_LINK_LIBRARIES(${PROJECT_NAME} line
- Open the *.vcproj file in the Visual Studio editor and find the <LibraryDependencies> line
- Copy the list of dependencies and paste it into your CMakeList.txt file
- Note you need to remove the ';' separators
- Copy the list of dependencies and paste it into your CMakeList.txt file
Remove section about POWERSHELL and validate_manifest script
This CMakeList.txt file that we started with is a great start because it's for the AzureIoT example and let's face it; If you're developing an Azure Sphere application, it's more than likely going to be connected to Azure. But, this CMakeList.txt file adds checks to make sure we've updated our app_manifest.json file for the actual AzureIoT example. We don't need that section. Use the graphic below to identify and remove all the lines inside the red box from your file.
My final CMakeList.txt file
Edit CMakeSettings.json
We're almost finished. The last thing we need to do is tell CMake about our TargetAPISet and our Hardware definitions.
- From inside Visual Studio, open the CMakeSettings.json file
- Click on the "Edit JSON" link at the top of the display
- Refer to the screenshot you took of your Visual Studio Project properties page and modify the three lines inside the "environments" object shown below. Make sure you use the settings from your Visual Studio project page that worked earlier.
Build and test our project
Hopefully you can now build and test your application. If things don't work navigate to the "Output" output tab to look for hints.
Remove the Visual Studio Project files from our project
You can clean up your project by removing the Visual Studio Project files now that you're ready to use CMake. I removed the file extensions listed below from my project without any adverse side effects.
- *.vxprod
- *.vcxproj.filters
- *.vcxproj.user
A note about the launch.vs.json file
If you're developing M4 applications along with your high level A7 applications you need to also modify the launch.vs.json file. There's a line in here called "partnerComponents" When you have more than one application running on your device this line needs to include the "Component ID" of the other application. This is similar to what you do in the app_manifest.json file with the "AllowedApplicationConnections" entry.
If you ever try to run two applications from two Visual Studio applications and the first one exits when you start the second application, remember this note! This is likely the issue, ask me how I know.
My notes on using CMake instead of Visual Studio projects
I understand why Microsoft went down the CMake path. They wanted to enable development across multiple platforms and IDEs and CMake supports that goal. There are a few things I've noticed that I'll share . . .
- CMake projects in Visual Studio don't break our the include files in one folder and the source files in another folder. They are all listed together, no big deal.
- I've noticed that it's a good idea to do a clean build after changing a build configuration
- Build --> Clean All
- I've seen cases where I start an application in the debugger and the application halts stating that it hit a break point in main.c when I did not set a break point
- Shut down Visual Studio and start it back up and the issue should clear
Closing
I hope this Blog helps you port your existing Visual Studio projects to CMake. You'll need to get this done before you update to the new 20.01 SDK due out anytime now. If you find other helpful hints please add a comment so we can help the community.
Thanks for reading,
Brian