DEV Community

HarmonyOS
HarmonyOS

Posted on

How to Customize App Builds in DevEco Studio

Read the original article:How to Customize App Builds in DevEco Studio

Problem Description

Sometimes developers want to build different versions of their app. For example: They want one app for free users, one for paid users, and one for testing. But the app does not build correctly.

The problem happens when targets are not set for the right product. Also, if the default product is missing, the build will fail.

Background Knowledge

DevEco Studio helps developers build apps for HarmonyOS. You can create many products in one project. Each product can have:

  • its own name
  • icon and label
  • bundle type (app or atomicService)
  • bundle name
  • vendor name
  • signature file

You can also set build modes:

  • debug for testing
  • release for publishing

Targets are parts of the app. Each target is for a different device or user group. You must link each target to a product.

Troubleshooting Process

We checked the build-profile.json5 file. We saw that some targets were not linked to products. We also saw that the default product was missing. We fixed the file by adding:

  • a default product
  • correct targets for each product
  • build modes: debug and release

Solution

We added three products:

  • default with target default
  • productA with target free
  • productB with target pay

We set bundle names, types, icons, labels, and signatures. We used applyToProducts to link targets to products. We added build modes: debug and release.

Defining products:

"app": { 
  "signingConfigs": [], 
  "products": [ 
    { 
      "name": "default", 
      "signingConfig": "default", 
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
    }, 
    { 
      "name": "productA", 
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
    }, 
    { 
      "name": "productB", 
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
    } 
  ], 
  "buildModeSet": [ 
    { 
      "name": "debug", 
    }, 
    { 
      "name": "release" 
    } 
  ] 
}
Enter fullscreen mode Exit fullscreen mode

Defining a Product's Package Name and Vendor Name Example:

{ 
  "app": { 
    "signingConfigs": [], 
    "products": [ 
      { 
        "name": "default", 
        "signingConfig": "default", 
        "compatibleSdkVersion": "5.1.1(19)", 
        "runtimeOS": "HarmonyOS", 
        "output": { 
          "artifactName": "customizedProductOutputName-1.0.0"  // The product name is customizedProductOutputName-1.0.0.
        }, 
        "vendor": "customizedProductVendorName"   // The vendor name is set to customizedProductVendorName.
      }, 
      { 
        "name": "productA", 
        "compatibleSdkVersion": "5.1.1(19)", 
        "runtimeOS": "HarmonyOS", 
        "output": { 
          "artifactName": "customizedProductOutputNameA-1.0.0"  // The product name is customizedProductOutputNameA-1.0.0.
        }, 
        "vendor": "customizedProductVendorNameA"   // The vendor name is set to customizedProductVendorNameA.
      }, 
      { 
        "name": "productB", 
        "compatibleSdkVersion": "5.1.1(19)", 
        "runtimeOS": "HarmonyOS", 
        "output": { 
          "artifactName": "customizedProductOutputNameB-1.0.0" // The product name is customizedProductOutputNameB-1.0.0.
        }, 
        "vendor": "customizedProductVendorNameB"   // The vendor name is set to customizedProductVendorNameB.
      } 
    ], 
    "buildModeSet": [ 
      { 
        "name": "debug", 
      }, 
      { 
        "name": "release" 
      } 
    ] 
  }, 
}
Enter fullscreen mode Exit fullscreen mode

Defining Bundle Names for Products Example:

"app": { 
  "signingConfigs": [], 
  "products": [ 
    { 
      "name": "default", 
      "signingConfig": "default",
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
      "bundleName": "com.example00.com"  // Define the bundle name for product default.
    }, 
    { 
      "name": "productA", 
      "signingConfig": "default",

      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
      "bundleName": "com.example01.com"  // Define the bundle name for productA.
    }, 
    { 
      "name": "productB", 
      "signingConfig": "default",
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
      "bundleName": "com.example02.com"  // Define the bundle name for productB.
    } 
  ], 
  "buildModeSet": [ 
    { 
      "name": "debug", 
    }, 
    { 
      "name": "release" 
    } 
  ] 
}
Enter fullscreen mode Exit fullscreen mode

Defining Bundle Types for Products:

"app": { 
  "signingConfigs": [], 
  "products": [ 
    { 
      "name": "default", 
      "signingConfig": "default",
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
      "bundleName": "com.example00.com",   
      "bundleType": "app" // Define the bundle type for product default.
    },
    { 
      "name": "productA", 
      "signingConfig": "default",
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
      "bundleName": "com.example01.com",    
      "bundleType": "atomicService"  // Define the bundle type for product productA.
    },
    { 
      "name": "productB", 
      "signingConfig": "default",
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
      "bundleName": "com.example02.com",    
      "bundleType": "atomicService"  // Define the bundle type for product productB.
    } 
  ], 
  "buildModeSet": [ 
    { 
      "name": "debug", 
    },
    { 
      "name": "release"
    } 
  ] 
}
Enter fullscreen mode Exit fullscreen mode

Defining Signature Information for Products:

You can set signature info in the Signing Configs page or in build-profile.json5.

"app": { 
  "signingConfigs": [], // After the signature information is configured from the GUI, the corresponding signature configuration is automatically generated here. It is omitted in this example for simplicity.
  "products": [ 
    { 
      "name": "default", 
      "signingConfig": "default", // Define the signature file for product default.
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
      "bundleName": "com.example00.com"  
    }, 
    { 
      "name": "productA", 
      "signingConfig": "productA", // Define the signature file for product productA.
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
      "bundleName": "com.example01.com"  
    }, 
    { 
      "name": "productB", 
      "signingConfig": "productB", // Define the signature file for product productB.
      "compatibleSdkVersion": "5.1.1(19)", 
      "runtimeOS": "HarmonyOS", 
      "bundleName": "com.example02.com" 
    } 
  ], 
  "buildModeSet": [ 
    { 
      "name": "debug", 
    }, 
    { 
      "name": "release" 
    } 
  ] 
}
Enter fullscreen mode Exit fullscreen mode

Defining Icons and Labels for Products:

When you build the app, the icon and label set in the product will overwrite the ones in the app.json5 file.

You can set these fields in both app.json5 and module.json5. To learn which one takes priority, check the Application- or Component-Level Configuration.

{
  "app": {
    "signingConfigs": [],
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "compatibleSdkVersion": "5.1.1(19)",
        "runtimeOS": "HarmonyOS",
        "icon":"$media:default_icon", // Define the icon for product default.
        "label":"$string:default_name", // Define the label for product default.
      },
      {
        "name": "productA",
        "signingConfig": "default",
        "compatibleSdkVersion": "5.1.1(19)",
        "icon":"$media:productA_icon", // Define the icon for product productA.
        "label":"$string:productA_name", // Define the label for product productA.
      },
      {
        "name": "productB",
        "signingConfig": "default",
        "compatibleSdkVersion": "5.1.1(19)",
        "runtimeOS": "HarmonyOS",
        "icon":"$media:productB_icon", // Define the icon for product productB.
        "label":"$string:productB_name",  // Define the label for product productB.
      }
    ],
    "buildModeSet": [
      {
        "name": "debug",
      },
      {
        "name": "release"
      }
    ]
  },
  ...
}
Enter fullscreen mode Exit fullscreen mode

Defining Targets for Products Example

{ 
  "app": { 
  "signingConfigs": [], // After the signature information is configured from the GUI, the corresponding signature configuration is automatically generated here. It is omitted in this example for simplicity.
    "products": [ 
      { 
        "name": "default", 
        "signingConfig": "default",
        "compatibleSdkVersion": "5.1.1(19)", 
        "runtimeOS": "HarmonyOS", 
        "bundleName": "com.example00.com"  
      }, 
      { 
        "name": "productA", 
        "signingConfig": "productA",
        "compatibleSdkVersion": "5.1.1(19)", 
        "runtimeOS": "HarmonyOS", 
        "bundleName": "com.example01.com"  
      }, 
      { 
        "name": "productB", 
        "signingConfig": "productB",  
        "compatibleSdkVersion": "5.1.1(19)", 
        "runtimeOS": "HarmonyOS", 
        "bundleName": "com.example02.com" 
      } 
    ], 
  "modules": [ 
    { 
      "name": "entry", 
      "srcPath": "./entry", 
      "targets": [ 
        { 
          "name": "default",  // Pack the default target into product default.
          "applyToProducts": [ 
            "default" 
          ] 
        }, 
        { 
          "name": "free",  // Pack the free target into product productA.
          "applyToProducts": [ 
            "productA" 
          ] 
        }, 
        { 
          "name": "pay",  // Pack the pay target into product productB.
          "applyToProducts": [ 
            "productB" 
          ] 
        } 
      ] 
    } 
  ] 
}
Enter fullscreen mode Exit fullscreen mode

Building a HAP and App Pack

In DevEco Studio, click the top right corner, pick the product and target, and press Apply.

You must select:

  • Product name
  • Build mode (debug or release)
  • Product info (bundle and signature)
  • Target (only if it belongs to the product)

Verification Results

We built the app in DevEco Studio:

  • ProductA built the free target
  • ProductB built the pay target
  • Default product built the default target

All builds worked. No errors.

Verifications and Link

Customizing Multi-Product Builds

Written by Mustafa Sahin

Top comments (0)