Skip to content

packages.json

This document describes the structure and usage of the packages.json file.

Overview

The packages.json file is the package management configuration for the project. Correspondingly, there is also a configs.json file for managing the IMakeCore system configurations.

In the Package Integration, we introduced the usage of the packages field in packages.json. This document will systematically introduce the structure and usage of packages.json.

The packages.json file is automatically generated by IMakeCore to manage the configuration of project dependencies. Its location is under the current directory of the project.

A typical packages.json file is as follows:

{
    "libstores": [],
    "forceLocal": true,
    "packages": {
        "ICmd": "*",
        "ICore": "*",
        "IRdb": "x",
        "asio": "*",
        "cpp-httplib": "*",
        "nlohmann.json": "*",
        "packaging": "*",
        "stachenov.quazip": "*",
        "zlib": "*"
    }
}

In the following content, the usage of this configuration will be explained in detail.

Fields in packages.json

forceLocal

The forceLocal field in the global scope is of type bool, with a default value of false.

If forceLocal is defined in the global scope, it affects all packages configured in packages.json. If a package is not configured with "forceLocal": false in the properties, its forceLocal value defaults to the global forceLocal value.

If a package's forceLocal value is true, the package will be copied to the project's package directory.

The priority order is: the specific package's forceLocal takes precedence over the global forceLocal. If a package's forceLocal is not defined, the global forceLocal value is used as a fallback.

Packages marked with forceLocal will be copied to the project's package directory during loading. For details about the project's package directory, refer to localLibStore.

For example:

{
    "forceLocal": true,
    "packages": {
        "lib1": "*",
        "lib2": "x",
        "lib3": {
            "version": "*",
            "forceLocal": false
        },
        "lib4": {
            "version": "x",
            "forceLocal": true
        }
    }
}

In the above example, lib1's forceLocal is true, so it will be copied to the project's package directory for loading. lib2's version is x, so the package is ignored and not loaded. lib3's forceLocal is false, so it is loaded according to IMakeCore's default loading rules. lib4's forceLocal is true, so it will also be copied to the project's package directory for loading.

Note that for the lib3 package above, if there is a matching package in the project's package directory with the same name and version, the loaded package will also come from the project's package directory.

Typically, a global forceLocal set to true is used in the following scenarios but is not limited to: - Users want to fix a package's version locally, preventing it from being downloaded from a remote repository for easier debugging and modification. - Users want to package the project along with its dependencies for compilation on different machines, eliminating the need to download dependencies from the network.

servers

The servers field's value is an array of strings, which can be empty by default. The strings inside the field must be server paths. Users can provide multiple server addresses for downloading packages.

The following are valid paths:

1
2
3
http://127.0.0.1:8000
https://abc.com
http://abc.com:81

Note that the paths here must be scheme + host format and cannot include path information. The following paths are invalid:

http://127.0.0.1/
http://abc.com/hello

The purpose of the servers field is to provide network-based package services. IMakeCore can query and download packages from the corresponding servers.

Servers defined earlier in the servers field take precedence over those defined later. The servers field in packages.json has higher priority than the servers field in the IMakeCore system configuration. During actual package querying and downloading, IMakeCore will call the server addresses in order of priority. If the first server cannot fulfill the request (e.g., connection issues or the package not being available), it will proceed to the next server in the list.

localLibStore

The localLibStore field defined in packages.json represents the current project's package directory. This field is a string corresponding to a folder path. The field can be omitted; if omitted, the default path is the .lib folder under the project directory. Users can define their own localLibStore path.

This field works in conjunction with the forceLocal field. If a package is marked with forceLocal, it will be stored in the localLibStore.

libStores

The libstores field's corresponding value is an array, representing a series of folders for storing packages. The libstores field can be omitted by default, and if omitted, it defaults to an empty array.

Note that the priority order is: localLibStore > libStores > libstore defined in the IMakeCore system.

The libStores defined in packages.json are only applicable to the current project and not to other projects. If users need to make a libStore available to all projects, they can configure it in the IMakeCore system.

If users have additional packages stored in different folders, they can add the corresponding folder paths to the libStores field. This will allow IMakeCore to recognize and process these packages.

packages

The content of the packages field is detailed in Package Integration. Here, we reproduce the content for completeness in describing the packages.json structure. Users already familiar with this content can ignore it.

Simple Package Configuration

All packages must be defined in the packages domain of the packages.json file. Their definition format is as follows:

name : version

The simplest method for integrating a package is in the form name : version. This specifies the package version. If the local environment does not have this version of the package, IMakeCore will attempt to pull it from the server. If the server pull fails, the version configuration fails. Users need to verify whether the package version exists.

The version format is xxx.xxx.xxx. For example, 1.0.0. Other formats, such as beta, are not currently supported.

Its usage is as follows:

1
2
3
4
5
6
{
    "packages":{
        "ICore" : "1.0.0",
        "asio" : "1.30.2"
    }
}
name : *

This form does not specify the exact version of the package.

When loading the package, IMakeCore will scan all locally available packages. If the package is found, the highest version found will be used for loading. If the package is not found, the latest version will be downloaded from the server and loaded.

There is one important point to note here: if users use * to import a package, they cannot guarantee loading the specific version they want. If users want the latest version and the locally available version is not the latest, the loaded version will still not be the latest. Users should specify the version number to load the latest version or use the ipc update command to update the local package to the latest version for loading.

name : x

Here, x is the character x ['eks]. Users can also use uppercase X for writing.

If a package is marked with x, it will be excluded from loading during package configuration.

IMakeCore defines this x to address the need where JSON files cannot comment out packages to be imported. Users can temporarily disable a package by using x as a configuration item.

More Complex Package Configuration

The above describes simple key-value pair configurations with string values that can be written on a single line.

IMakeCore supports more complex configurations, allowing users to define additional information for a package. In this case, the value of the key-value pair is no longer a string but an object, as shown below:

{
    "packages":{
        "MyLib" : {
            "version" : "*",
            "path" : "c:/mylib_path/MyLib",
            "url" : "https://github.com/MyName/MyLib/MyLib.zip",
            "forceLocal" : true
        }
    }
}

In the above configuration, users can specify complex content to meet their needs for personalized configuration.

Let's now explain the meaning of each attribute in the object.

version

Here, version is generally the same as the version in the simple package configuration. Users can set a specific version, use * to accept any version, or use x to indicate that the package should not be resolved or loaded.

version is a required field. Users must declare the package's version, even if it is *.

path

The path value is a string.

Here, path is the local path of the package. If users configure a local path, IMakeCore will load the package from there. Consequently, if the package is not found in this path, a package loading error will occur, and users need to manually verify the package's existence and version consistency.

The path can be omitted. If omitted, IMakeCore will use other paths for loading.

If users specify a path, it has the highest priority. IMakeCore will only query the package from this path.

url

url can be a string representing a URL path or a string array representing multiple paths.

Here, url is the download address for the package. If users do not configure a local path or cannot find the package locally, IMakeCore will use the specified url in order to download and attempt to parse and load the package.

If multiple URLs are specified and the first URL downloads a package that does not match the configured package, IMakeCore will not attempt to download or parse subsequent packages but will report an error directly. Users need to manually verify the package configuration in this case.

The url can be omitted.

forceLocal

The forceLocal value is of type bool, with a default value of false.

If forceLocal is true, it means the package must be loaded from the package folder under the project directory. If the package is not found in the project directory's package folder, IMakeCore will copy the package to that location and proceed with loading.

The default project directory package folder is the .lib folder under the project directory. Users can also configure other paths in the package.json.

The rationale for the forceLocal field is as follows:

  • Users want to make changes to a package to meet specific requirements. Directly modifying the package would contaminate it, potentially causing issues in other projects. Copying it to the project directory avoids this problem.
  • Users want to share the project by copying it, and the destination may not have IMakeCore installed, or may be offline, or they want to directly copy and compile. Copying the dependency packages to the project folder is an effective solution.

The forceLocal field can be configured not only within the package properties but also in the public domain of packages.json. For specific usage, refer to forceLocal.