☁️ Build C++ Windows Application with Custom Executor on Huawei Cloud CodeArts

Yagiz Karakus
Huawei Developers
Published in
7 min readSep 2, 2024
CodeArts

Introduction

In this demo, we will walk through the process of setting up, building, and deploying a Windows C++ project using Huawei Cloud’s CodeArts platform. This step-by-step guide is designed to help you configure your development environment, create a project repository, and execute a build task using modern tools like Microsoft Visual Studio 2022 Build Tools, Git, and Docker.

We’ll start by preparing your Windows machine with the necessary prerequisites, including installing the required build tools, Git, Docker, and Java 8 Development Kit. Following that, we’ll create and configure a C++ project repository based on a template, ensuring it is compatible with the latest Visual Studio version. Finally, we’ll demonstrate how to set up a build agent, create a build task, and run it to generate an executable file from your C++ project, which can be downloaded and executed from the Huawei Cloud platform.

This demo is perfect for developers looking to streamline their C++ development and deployment workflow using cloud-based CI/CD tools. By the end of this session, you’ll have a fully functional C++ build pipeline up and running, capable of producing executable files ready for distribution.

Demo

Prerequisites

Before starting demo we need a Windows machine and install msbuildtools in it you can install it with the following command in PowerShell

winget install Microsoft.VisualStudio.2022.BuildTools --force --override `
"--wait --passive --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
--add Microsoft.VisualStudio.Component.Windows11SDK.22000 `
--add Microsoft.VisualStudio.Component.VC.143 `
--add Microsoft.VisualStudio.Component.VC.ATLMFC"

You also need git and docker installed on your computer and you also need to install Java 8 development kit but it must be x64(32-bit version).

Setup-1 Create Project and Repository

Go to the repository page from the side menu and click “Create Repository”.

Select Template and choose “Windows Cpp Demo” template you can filter template project by the programming language.

This template project was built based on msbuildtools 15 but we will use the newer version of msbuildtools so we need to update CppDemo.rc and CppDemo.vcxproj files for our target environment.

Go to the file you will update (They are under the CppDemo folder) then click the edit button (pencil icon) on the upper left of the file previewer. then paste the new file content for the related file and click “OK” under the page.

<!-- CppDemo.vcxproj -->
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{54B50897-3540-4EC9-9DEF-C2AFD71654AA}</ProjectGuid>
<RootNamespace>CppDemo</RootNamespace>
<Keyword>MFCProj</Keyword>
<PlatformToolset>v143</PlatformToolset> <!-- Updated for Visual Studio 2022 -->
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset> <!-- Updated for Visual Studio 2022 -->
<UseOfMfc>Static</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset> <!-- Updated for Visual Studio 2022 -->
<UseOfMfc>Static</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>17.0.31903.102</_ProjectFileVersion> <!-- Updated for Visual Studio 2022 -->
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(DXSDK_DIR)include;$(IncludePath)</IncludePath>
<LibraryPath>$(DXSDK_DIR)\lib\x86;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(DXSDK_DIR)include;$(IncludePath)</IncludePath>
<LibraryPath>$(DXSDK_DIR)\lib\x86;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>false</ValidateAllParameters>
</Midl>
<ClCompile>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0804</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>false</ValidateAllParameters>
</Midl>
<ClCompile>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0804</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="KnightScanLineZbuffer\Algorithm.h" />
<ClInclude Include="KnightScanLineZbuffer\KnightActiveList.h" />
<ClInclude Include="KnightScanLineZbuffer\KnightBucket.h" />
<ClInclude Include="KnightScanLineZbuffer\KnightBuffer.h" />
<ClInclude Include="KnightScanLineZbuffer\KnightScanLineZbuffer.h" />
<ClInclude Include="CppDemo.h" />
<ClInclude Include="CppDemoDoc.h" />
<ClInclude Include="CppDemoView.h" />
<ClInclude Include="MainFrm.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="KnightGlobal\KnightGlobal.h" />
<ClInclude Include="KnightDebug\KnightDebug.h" />
<ClInclude Include="KnightMesh\KnightMesh.h" />
<ClInclude Include="KnightMesh\KnightObj.h" />
<ClInclude Include="KnightMesh\KnightTriple.h" />
<ClInclude Include="KnightMath\KnightMath.h" />
<ClInclude Include="KnightEngine\EngineMain.h" />
<ClInclude Include="KnightEngine\KnightDefine.h" />
<ClInclude Include="KnightEngine\KnightEngine.h" />
<ClInclude Include="KnightEngine\KnightEngineInterface.h" />
<ClInclude Include="KnightEngine\KnightOpenGL.h" />
<ClInclude Include="copyright.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="KnightScanLineZbuffer\KnightActiveList.cpp" />
<ClCompile Include="KnightScanLineZbuffer\KnightBucket.cpp" />
<ClCompile Include="KnightScanLineZbuffer\KnightScanLineZbuffer.cpp" />
<ClCompile Include="CppDemo.cpp" />
<ClCompile Include="CppDemoDoc.cpp" />
<ClCompile Include="CppDemoView.cpp" />
<ClCompile Include="MainFrm.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="KnightDebug\KnightDebug.cpp" />
<ClCompile Include="KnightMesh\KngihtObj.cpp" />
<ClCompile Include="KnightMesh\KnightMesh.cpp" />
<ClCompile Include="KnightEngine\EngineMain.cpp" />
<ClCompile Include="KnightEngine\KnightOpenGL.cpp" />
</ItemGroup>
<ItemGroup>
<Image Include="res\CppDemo.ico" />
<Image Include="res\CppDemoDoc.ico" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="CppDemo.rc" />
</ItemGroup>
<ItemGroup>
<None Include="res\CppDemo.rc2" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties RESOURCE_FILE="CppDemo.rc" />
</VisualStudio>
</ProjectExtensions>
</Project>

CppDemo.rc

Change “CppDemo.rc” file as follows.

update CppDemo.rc file

Old file value

VALUE "LegalCopyright", "TODO: (C) <CppDemo>。all rights reserved。"
VALUE "OriginalFilename", "cppDemo.exe"

New file value

VALUE "LegalCopyright", "TODO: (C) <CppDemo>. All rights reserved."
VALUE "OriginalFilename", "CppDemo.exe"

Step-2 Setup Agent

Go to the Huawei Cloud Console and from the top right open My Credentials.

My Credentials

Go to the Access Keys page from the side menu and click “Create Access Key”.

Then you can download your access key and store it safely on your computer. In the following steps, we will use it.

Create Access Key

Go to the Build page in Code Arts from the side menu. Select Pools from the dropdown button placed at the top of the page

go to Pools page

Click “Create Pool” button and give your pool a name and select Pool type as Windows then save your pool.

Setup Pool

Open your pool by clicking its name. And on the following page, click “Create Agent” button

Click Create Agent in the top right and enter the Access Key and Secret Key from the credentials you observe above. Then generate command and run in the git bash.

Generate Command

After the command runs successfully you are ready to create a Build Task.

Run command on git bash

Step-3 Create Build Task

Go to the Build page from the side menu and click “+ Create Task” button.

Fill in the basic information. Select the repository we created then click “NEXT”.

Fill Basic Information

Select Blank Template and click “OK”

Create Blank Template

Then select “custom executor” and select your agent pool also choose your build environment’s architecture.

Configure Build Environment

Add Build actions as follows “Run Shell Commands” and “Upload to Release Repo”

Run Shell Command

Update run shell command

Paste the following code to your run shell command action.

powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "& 'C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/Common7/Tools/Launch-VsDevShell.ps1' ; msbuild /p:OutputPath=../buildResult/Release/bin"

powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "Compress-Archive -Path ./Debug -DestinationPath ./archive.zip"

We compress our build files as archive.zip so we update the “Upload to Release Repo” action according to that.

Update “Upload to Release Repo” action

Step-4 Run Build Task

Finally, Save and Run the Build Task from the top right button.

After it runs successfully open Release Repo under the Artifacts from the side menu.

Build Task run successfully

Now you can observe and download your Visual C++ project as an exe.

Executable file compressed under release repo

And you can run from the executable file.

Built application

Conclusion

In this demo, we successfully navigated through the entire process of setting up, building, and deploying a Windows C++ project using Huawei Cloud’s CodeArts platform. Starting with the installation of essential tools like Microsoft Visual Studio 2022 Build Tools, Git, Docker, and the Java 8 Development Kit, we laid a solid foundation for our development environment.

We then created a C++ project repository based on a pre-existing template, updating it to align with the latest Visual Studio standards. Following that, we configured a build agent and crafted a custom build task tailored to our project’s requirements. Finally, we executed the build task, resulting in a compiled executable that was successfully uploaded to the release repository, and ready for distribution.

This process highlighted the efficiency and flexibility of using cloud-based CI/CD tools to manage and automate the build and deployment of C++ projects. By leveraging the power of Huawei Cloud’s CodeArts, you can streamline your development workflow, ensuring that your applications are built and deployed consistently and reliably.

Thank you for following along with this demo. We hope it has provided you with valuable insights and practical skills to enhance your C++ development practices.

--

--