This article briefly introduces how to develop an Apollo extension module, with a simple example of how to create the project code of an extension module and the role of the necessary files contained in it. It alos explains how to use the buildtool to compile the extension module.
To read this article you need a preliminary grasp of
- How to use Bazel to build C++ projects https://docs.bazel.build/versions/5.1.0/tutorial/cpp.html
- Introduction to using Apollo buildtool
The package is not just a .deb file in a broad sense, but contains a variety of forms throughout the cycle, from code to dependencies. The package can be divided into 5 types: source, local compilation, packaging, remote, and local installation.
Forms | Role | Generation method/Time | Storage Location | Usage | Remarks |
---|---|---|---|---|---|
source | Create the source code files for the package | Developed by developers | git code repository | Ordinary source code files containing some of the file contents necessary for the specification | |
local compilation | Compile and generated content ready for packaging and distribution | Compile and install | local repository (located in /opt/apollo/neo/packages) | Generated by local code compiled in the local environment, containing local modifications | Can also be used as a dependency, component |
packaging | Make a .deb package ready for release | Packing Production | Generally in the packing tool working directory | The deb package is the same as other deb packages and can be installed using the system's dpkg and other tools. | |
remote | Deb packages published to remote repositories and made available to developers across the network | release | apt source | Download and install via apt (or buildtool) | |
local installation | Packages installed locally using the apt tool, which can be loaded as dependencies or components | apt install or buildtool install | local repository(located in /opt/apollo/neo/packages) | Used as a Cyber component to load, used as a general dynamic library SO, etc. |
Module extension is the process of creating new or modifying the code of an existing module and publishing the module. The following figure shows the workflow of module extension:
Next, we will introduce the complete workflow of the module extension project and the considerations of each node through the demo project.
First install Docker and start the Apollo Env container, then use buildtool to initialize a demo project:
buildtool init -w
The demo project directory structure is as follows:
.
|-- WORKSPACE
`-- example_components
|-- BUILD
|-- cyberfile.xml
|-- example-components.BUILD
|-- example.dag
|-- example.launch
|-- proto
| |-- BUILD
| `-- examples.proto
`-- src
|-- BUILD
|-- common_component_example.cc
|-- common_component_example.h
|-- timer_common_component_example.cc
`-- timer_common_component_example.h
The demo project is described in detail next:
- src: holds all the source code of the demo project.
- proto: holds the proto message format definition of the demo project.
- component launch files: example.dag and example.launch, which define how to launch example-component.
- BUILD: bazel compilation description file, which will be further described in the compilation description file section.
- cyberfile.xml: package description file, similar to package.xml in ros, which will be described in the module description file section.
- example-components.BUILD: Through this file, other modules can use the symbols and functions of example-components, which will be further described in the section on dependency description files.
- WORKSPACE: Bazel workspace markup file, further described in the section WORKSPACE files and workspaces.
WORKSPACE i.e. Bazel's workspace, it is a directory, the Demo project directory is a workspace which contains all the files of the extension module (including source files and build output, etc.), which also contains some special files such as WORKSPACE, BUILD, cyberfile.xml, etc.
The WORKSPACE file, Bazel's WORKSPACE file, identifies the directory and its contents as a Bazel workspace and is located in the root directory of the project directory structure. The WORKSPACE file can be an empty file, but it can also define space names or download and initialize dependencies. when Bazel builds a project, all inputs and dependencies must be located in the same workspace. Unless linked, files in different workspaces are independent of each other.
Apollo buildtool will process the WORKSPACE file, injecting common dependency tools and initializing the dependency packages declared in the cyberfile.xml file (see Appendix: WORKSPACE File Injection for details).
Writing the source code is the actual module development process. Demo projects already come with example-component source code, so there is no need to write and modify any source code for demo projects.
In the actual development, the developer needs to write the code of the module to be developed or develop it based on the existing module source code.
For developing modules from scratch, buildtool provides a useful command to initialize the module.
buildtool create --type src $YOU_MODULE_PATH
For secondary development scenarios, buildtool provides a useful command to copy the source code into a workspace:
buildtool install planning-dev
This command copies the source code of the planning module to the workspace, which is stored in the module/planning folder.
Note: The above command needs to be run under the workspace.
For bazel, developers need to write BUILD files according to bazel's specifications in order to compile the modules, which can be found in the official bazel tutorial or in the Appendix: BUILD Files and Package Dependencies.
In addition to the bazel specification, in order to achieve Apollo package management, the following Apollo specifications should be followed when writing BUILD files.
- Add two additional Apollo custom rules: install, install_src_files to the BUILD file in the root directory of the module (For example, the root directory of the planning module is modules/planning) install and install_src are two extension rules that serve to install build output into the local repository of Apollo packages (i.e. /opt/apollo/neo/packages directory). install rule installs build output into the local repository, while install_src rule installs the source code to the local repository, and the installation result supports preserving the source code directory structure. These two rules mainly serve the package approach to use Apollo. Using buildtool to compile must define these two extended rules in the BUILD file at the top level of the module, otherwise the compilation will fail. Use as shown in the demo:
install(
name = "install",
data = [
"//example_components/proto:examples_cc_proto",
":cyberfile.xml"
],
data_dest = "example-components",
library_dest = "example-components/lib",
library_strip_prefix = ["src", "proto"],
targets = [
"//example_components/src:libcomponent_examples.so",
"//example_components/proto:examples_cc_proto"
],
deps = [
":pb_headers",
":dag",
":launch"
]
)
install_src_files(
name = "install_src",
src_dir = ["."],
dest = "example-components/src",
filter = "*",
deps = [
":headers"
]
)
- install
- data: install as data file
- data_dest: the installation directory of the data file, the installation directory is /opt/apollo/neo/package/ relative directory, and the installation directory (xxx_dest) should be set to be the same as the package name. data_dest in the demo is set to example-components, which is the same as the package name. In demo example, data is directly installed in the package directory.
- library_dest: the installation directory of dynamic library files (*.so), same as data_dest specification. library_dest in the demo is set to example-components/lib. In demo example, .so files are installed in the lib directory of the package.
- targets: the list of installed target files.
- deps: other targets that the rule depends on.
- install_src_files
- src_dir: the directory where the target source code is installed.
- dest: the location of the source code installation, again, the installation directory should be set to the src directory under the package name directory (header files should be set to the include directory of the package directory). For example, the demo is set to example-components/src.
- filter: filtering target files by file name, "*" means all files.
- deps: other targets that the rule depends on. Note: The first-level directory of the above dest-related properties should be consistent with the name in cyberfile.xml. For example, the name in cyberfile.xml in the demo project is example-components, so the install and install_src_files rules in the dest related properties in the install and install_src_files rule have example-components as the first level directory. Failure to follow this rule can lead to problems with the module not being imported as a dependency.
- When the output of a module is a dynamic library that needs to be loaded dynamically, additional options need to be added to the native cc_library and cc_binary rules. A component is a dynamic library loaded by Apollo middleware cyber-rt, e.g., perception, location, etc. Developers who want to extend new functionality based on their own scenario generally create a new component. The main content of the component is the compiled output dynamic library SO file, and is different from the dependency library SO files, so they are generally not used as compiled dependencies by other modules/packages. To successfully build a component into a package the following items need to be noted when writing the BUILD file:
cc_binary(
name = "libcomponent_examples.so",
linkshared = True,
linkstatic = True,
deps = [
":timer_common_component_example_lib",
":common_component_example_lib"
],
)
cc_library(
name = "timer_common_component_example_lib",
srcs = ["timer_common_component_example.cc"],
hdrs = ["timer_common_component_example.h"],
visibility = ["//visibility:private"],
alwayslink = True,
deps = [
"//cyber",
"//example_components/proto:examples_cc_proto",
],
)
- Use cc_binary to compile dynamic libraries, and the name should be in the format of libxxxxx.so, i.e. starting with lib and ending with .so.
- The linkshared and linksstatic attributes are set to True.
- If the dependent target is compiled by cc_library, then alwayslink must be set to True.
- When there is a specific part of the module that needs to be depended on by other modules (i.e. the module is used as a dependency library), the BUILD file needs to be written according to a specific specification. Dependency libraries are packages that will be depended on by other modules/packages when they are compiled. Under the Bazel compilation system, cc_library is generally used to write targets for other rules to use as dependencies, while Apollo packages need to make these dependencies into packages for distribution. Bazel's cc_library rules cannot meet the demand by default, so it needs to be combined with cc_binary rules and the necessary attribution to make a complete SO library. Take cyber_core as an example:
cc_binary(
name = "libcyber_core.so",
srcs = glob([
"cyber.cc",
"cyber.h",
]),
linkshared = True,
linkstatic = True,
linkopts = ["-lrt"],
deps = [
"//cyber:binary",
"//cyber:init",
...
],
visibility = ["//visibility:public"],
)
cc_library(
name = "cyber_core",
srcs = ["libcyber_core.so"],
hdrs = ["cyber.h"],
linkopts = ["-lrt"],
visibility = ["//visibility:public"],
deps = [
"@com_github_google_glog//:glog",
"@com_google_protobuf//:protobuf",
"@fastrtps",
"@com_github_gflags_gflags//:gflags",
"//cyber/proto:run_mode_conf_cc_proto",
...
],
includes = ["."],
)
- First write a dynamic SO library using cc_binary with reference to the configuration of the component SO. Pay attention to the name and linkshared, linkstatic properties settings.
- Then use cc_library to "wrap" the SO
- The srcs property is set to the target of the previous cc_binary, i.e. libcyber_core.so.
- hdrs contains the header files that need to be exposed to other modules.
- includes is also recommended to contain the headers that need to be exposed to other modules.
- deps contains the secondary dependencies to be passed.
The BUILD file of the demo project follows the above Apollo specification, and developers can refer to the BUILD file of the demo project.
cyberfile.xml is a module description file used to describe the information related to a module made into a package, such as package name, version number, dependent packages, etc.
cyberfile.xml is located in the root directory of the module in the workspace. The directory containing the cyberfile.xml file is the source form of a package (as shown in the demo source structure above), and its subdirectories are not allowed to have cyberfile.xml files, i.e. packages do not support nesting. After compilation and installation, the package is installed in the local repository (i.e. /opt/apollo/neo/packages directory) and becomes a local installation, see Local repository and package installation form for details. The package directory must have a BUILD file in addition to the required cyberfile.xml file (i.e., the directory is also a Bazel module).
The writing of the dependency information needs to be focused on, such as the cyberfile.xml shown in the demo.
<package>
<name>example-components</name>
<version>1.0.0.0</version>
<description>
example component
</description>
<maintainer email="apollo-support@baidu.com">apollo-support</maintainer>
<type>module</type>
<src_path>//example_components</src_path>
<license>BSD</license>
<author>Apollo</author>
<depend type="binary" src_path="//cyber" repo_name="cyber">cyber-dev</depend>
<depend>bazel-extend-tools-dev</depend>
<depend lib_names="protobuf" repo_name="com_google_protobuf">3rd-protobuf-dev</depend>
<depend expose="False" condition="gpu">3rd-gpus-dev</depend>
<builder>bazel</builder>
</package>
- name: the name of the package, Apollo global unique, if you need to publish the package to the official web, it is better to add a specific identifier to prevent conflicts when naming.
- version: package version number, strictly follow Ubuntu package naming convention: <1><2>-<3><4>.deb.
- <1>Package Name: omitted, use the name field to take the value directly.
- <2>Version Number: three numbers separated by dots are recommended, such as 1.0.1.
- <3>Build Number: one number is recommended, such as 1.
- <4>Architecture: omitted, need to be configured when releasing the package.
- src_path: the location of the module source code in the workspace.
- depend: dependency package information, i.e. the name of the declared dependency package, e.g. cyber-dev. Because of the type of dependency package and how it is used, this field also supports the configuration of the following attributes.
- type: the way the module is introduced, binary means using a compiled binary dependency from the package, src means using a binary dependency compiled from the workspace source code.
- src_path: the path where the source code of the dependency is stored in the workspace, usually no need to specify.
- repo_name: generally the package name, some third-party packages may have a specific name.
- lib_names: the name in the cc_library of the dependency xxx.BUILD file.
- expose: whether to expose the dependency to the rest of the modules as a secondary dependency.
- condition: the dependency is used only when compiled under certain conditions. The attributes in the depend tag above are more complex. Each package released on the apollo website has a default value for the depend attribute, so you don't need to modify it, you can just use it.
- builder: the compilation system type, currently supports bazel.
xxx.BUILD file is not needed in the scenario of a new extension of a component, it is only needed when making dependent packages (i.e. packages that can be used as dependencies for other modules), such as the cyber package. So its main role is to be introduced as a dependency to other modules to form the description file of Bazel's dependency. Take cyber.BUILD as an example:
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "cyber",
includes = ["include"],
hdrs = glob(["include/**/*"]),
srcs = glob(["lib/**/lib*.so*"]),
include_prefix = "cyber",
strip_include_prefix = "include",
visibility = ["//visibility:public"],
)
Some of the points to note are:
- name: lib name. When used as a dependency library, the name needs to be configured on the lib_names attribute in the depend sticky in cyberfile.xml (package name is used by default). Thus this field needs to be updated with great care, which may cause the compilation of the dependent parties to fail.
- includes: (system library) header search directory, generally contains "include", that is, the soft package directory of the include directory, install specification requires the installation of header files to the package's include directory.
- hdrs: (sandbox environment) the imported of the header files, here imported all the header files under the include folder.
- srcs: contains the dynamic library SO files of the package.
- include_prefix: configured according to the actual situation.
- strip_include_prefix: configured according to the actual situation. in demo, demo include a cyber headers according to:
#include "cyber/component/component.h"
while component.h is stored in "include/component/component.h". thus include_prefix is "cyber" while strip_include_prefix is "include".
- visibility: must be set to public.
As you can see above, the Apollo extension project adds support for Apollo package dependencies to the Bazel project specification, so it cannot be compiled directly using the Bazel command (mainly because of the lack of package dependencies), and requires some manual operations or configurations, such as downloading packages, converting packages into Bazel dependencies library into the project, etc. So to simplify the whole process, use buildtool to quickly compile. Just execute the following command to compile the extension project code into the local installation form of the package (for details of the local installation form and local libraries, please refer to Appendix: Local Repositories and Installation Form).
buildtool build --packages example_components
Take the common module as an example of how to compile, make packages and verify its functionality.
Developers need to:
- Download the common source code to the workspace,
- Compile,
- Write the release description file,
- Call buildtool to package the compiled output,
- Verify whether the package is available.
Next, each step will be described in detail.
In the workspace enter the following command:
buildtool install common-dev
use buildtool to build:
buildtool build --p modules/common
In this case, we use the following release description file:
{
"linux_distribution": "Ubuntu 18.04.5 LTS",
"kernal": "Linux 5.4.0-42-generic",
"arch": "x86_64",
"image": "registry.baidubce.com/apollo/apollo-env-gpu:0.0.4-dev",
"apollo_distribution": "neo",
"package_info": {
"type": "local",
"source": "/apollo_workspace/modules/common",
"build_ops": []
},
"release_detail": {
"name": "common",
"ver": "1.0.0.1",
"arch": "amd64",
"description": "Apollo common module.",
"deps": [
"3rd-rules-python-dev", "3rd-grpc-dev", "3rd-gflags-dev", "3rd-absl-dev", "libsqlite3-dev",
"3rd-rules-proto-dev", "3rd-eigen3-dev", "3rd-osqp-dev", "3rd-boost-dev", "3rd-gtest-dev",
"cyber-dev", "cyber-dev", "3rd-py-dev", "3rd-nlohmann-json-dev", "common-msgs-dev", "latency-proto-dev",
"3rd-bazel-skylib-dev"
],
"preinst_extend_ops": [],
"postinst_extend_ops": [
# create conf dir and grant permission
"mkdir -p /apollo/modules/common",
"chmod a+rw /apollo/modules/common",
# delete old config file
"if [ ! -f /apollo/LICENSE ]; then rm -rf /apollo/modules/common/data; fi",
"if [ ! -f /apollo/LICENSE ]; then rm -rf /apollo/modules/common/vehicle_model; fi",
# ln output config file to config dir
"if [ ! -f /apollo/LICENSE ]; then ln -snf /opt/apollo/neo/packages/common-dev/latest/data /apollo/modules/common/data; fi",
"if [ ! -f /apollo/LICENSE ]; then ln -snf /opt/apollo/neo/packages/common-dev/latest/vehicle_model /apollo/modules/common/vehicle_model; fi"
],
"prerm_extend_ops":[],
"postrm_extend_ops":[]
"data": [
{
"src": "common-dev/local",
"des": "-"
}
]
}
}
Next, the meaning of each field is explained.
linux_distribution: the linux distribution used, currently this field can only be filled with Ubuntu 18.04.5 LTS, which does not affect the packaging behavior.
kernal: linux kernel version, usually Linux 5.4.0-42-generic, this field currently does not affect the packaging behavior.
arch: cpu architecture, currently only supports x86_64.
image: the Apollo image used when compiling the source code, fill in the actual value based on the actual situation.
apollo_distribution: Apollo version code, currently only neo.
package_info: information related to the source code of the package to be compiled.
type: source code type, currently only supports local storage, that is, the source code is stored locally.
source: source code storage path, fill in the actual path.
build_ops: compile command set, a field reserved for future extensions, currently left empty.
release_detail: information related to the release.
name: the name of the package, must be consistent with the cyberfile.xml in the source code. For example, the name of cyberfile.xml in this example is "common", so the name of the release description file is also "common".
ver: package version, defined by the developer.
arch: architecture, currently only amd64 can be used.
description: the description of the package, the developer can fill in as needed.
deps: the dependency of the package. Strictly speaking it should be the same as the dependency in cyberfile.xml, but it is not mandatory. If the release description file is not exactly the same as the dependency in cyberfile.xml, it may cause errors in the actual use.
preinst_extend_ops: a shell operation to be executed before the package is installed.
postinst_extend_ops: the shell operation that will be executed after the package is installed.
prerm_extend_ops: the shell operation that will be executed before the package is removed.
postrm_extend_ops: the shell operation that will be executed after package deletion.
Note: The above four options can be filled in by the developer as needed. For all current apollo modules, all configuration files are read under /apollo, and the current package installation location is /opt/apollo/neo/packages. Therefore, it is necessary to softlink the package configuration files to the corresponding path of /apollo, and this operation postinst_extend_ops is performed. At the same time, since the package is compatible with the source image, the full amount of Apollo source code already exists in the source image, and the configuration file and source code under /apollo cannot be deleted. For detailed information about implementation, please refer to the description file in this example.
data: the file to be wrapped into a package.
src: path to the output file.
dst: the path to which the output file will be installed after the package is installed.
For example, in the above example src is common-dev/local, which is a relative path, corresponding to /opt/apollo/neo/packages/common-dev/local.
src can also be specified as an absolute path, e.g. directly into /opt/apollo/neo/packages/common-dev/local.
dst refers to the path where the files or folders in src will be installed after the package is installed by other users.
This example uses the default value of "-", which means that everything in /opt/apollo/neo/packages/common-dev/local will be installed to /opt/apollo/neo/packages/common-dev/${version}, where ${version} is the value corresponding to the vec field of the release description file.
Assuming that the release description file written in the previous step is named common.json.
Simply enter the following command:
buildtool pack -d common.json
The packed package is located in the .deb_local folder under the path of the execute package command.
Verify whether the package is available.
There are two types of modules, public dependency modules that provide the base interface (e.g. common module in this example) and modules that can be loaded or run independently (e.g. planning, perception, v2x).
For the public dependency modules, after installation, let other modules (e.g. planning) depend on the module in cyberfile.xml and compile it to verify that the public dependency module functions properly.
For modules that can be loaded or run independently, execute the binaries directly after installation, or launch the corresponding dag file or launch file to verify functionality.
Using v2x as an example:
- Install the already packed package.
cd .deblocal && sudo apt install -y ./apollo-neo-v2x-dev_1.0.0.2_amd64.deb
- Access the module installation location.
cd /opt/apollo/neo/packages/v2x/1.0.0.2
- Start the dag or run the binary executable directly.
mainboard -d dag/v2x_perception_fusion.dag
./bin/v2x
BUILD file that is Bazel's file, a WORKSPACE can contain one or more BUILD files. These files tell Bazel how to build different parts of the project. Bazel will contain the BUILD file directory as a Bazel module processing, and support nesting. That is, the subdirectory containing the BUILD file directory can also contain BUILD files, and Bazel will be treated as two modules.
A BUILD file contains several different types of instructions for Bazel. The most important type is a build rule, which tells Bazel how to build the desired output, such as an executable binary or library. Each instance of a build rule in a BUILD file is called a target and points to a specific set of source files and dependencies. A target can also point to other targets.
Dependent packages can be declared in the cyberfile.xml file, and when building with buildtool, buildtool automatically injects the dependent modules declared in cyberfile.xml as dependencies into the deps attribute of the three build rules in cc_binary cc_libary cc_test (if the deps attribute already contains the dependency, it will be overwritten automatically) to implement the package dependency.
For example, the demo has a dependency on the cyber package. First add the cyber package dependency in the cyberfile.xml file (see the cyberfile.xml description for details of the fields), and then use //cyber directly in the deps attribute of the cc_library rule of the target that depends on the cyber module to introduce the cyber dependency, just like the source code of cyber is used as if it were located directly in WORKSPACE.
The rules commonly used in BUILD files are:
- cc_binary: There are two main scenarios, one is to compile executable files, such as mainboard, etc. The other is used when compiling dynamic libraries, especially when compiling dynamic libraries that depend on other modules, you need to use together with cc_library, see Component SO and Dependency SO for details.
- cc_libary: Bazel dependency.
- cc_test: unit test.
- install: extension rules, install output to local repository, see install rules and install_src rules for details.
- install_src: extension rules, install source files to local repository, see install rules and install_src rules for details.
The WORKSPACE file is the configuration file of the Bazel workspace. In order to simplify the configuration of some of the necessary dependencies in the Apollo component extension scenario, the buildtool will modify the WORKSPACE file under the workspace during compilation and inject the relevant configuration, so you can see the following addition to the WORKSPACE file after compilation:
#######################################APOLLO#######################################
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "build_bazel_rules_apple",
sha256 = "0052d452af7742c8f3a4e0929763388a66403de363775db7e90adecb2ba4944b",
urls = [
"https://apollo-system.cdn.bcebos.com/archive/8.0/rules_apple.0.31.3.tar.gz",
"https://github.com/bazelbuild/rules_apple/releases/download/0.31.3/rules_apple.0.31.3.tar.gz",
],
)
http_archive(
name = "rules_foreign_cc",
sha256 = "6041f1374ff32ba711564374ad8e007aef77f71561a7ce784123b9b4b88614fc",
strip_prefix = "rules_foreign_cc-0.8.0",
urls = [
"https://apollo-system.bj.bcebos.com/archive/6.0/rules_foreign_cc-0.8.0.tar.gz",
"https://github.com/bazelbuild/rules_foreign_cc/archive/0.8.0.tar.gz",
],
)
load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
rules_foreign_cc_dependencies()
http_archive(
name = "rules_cc",
urls = ["https://apollo-system.cdn.bcebos.com/archive/8.0/rules_cc-0.0.1.tar.gz", "https://github.com/bazelbuild/rules_cc/releases/download/0.0.1/rules_cc-0.0.1.tar.gz"],
sha256 = "4dccbfd22c0def164c8f47458bd50e0c7148f3d92002cdb459c2a96a68498241",
patches = ["//tools/package:rules_cc.patch"],
)
load("//dev/bazel:deps.bzl", "init_deps")
init_deps()
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
grpc_deps()
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
grpc_extra_deps()
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
rules_proto_dependencies()
rules_proto_toolchains()
#######################################APOLLO#######################################
- All modifications are made by a pair of "##... .APOLLO... ##" fields, and buildtool checks them to prevent duplicate injections. It is also recommended not to modify this section.
- It contains some typical tools that Bazel depends on when compiling, such as build_bazel_rules_apple, rules_foreign_cc, rules_cc and other rules and dependencies.
- init_deps(): this function is the entry function to load the package into the Bazel dependency.
A brief description of the organization of the package in the local repository after installation. The so-called entity of the local repository is a directory, and the contents of the directory need to be organized in a way that conforms to the package specification. The details are as follows:
/opt/apollo/neo/
|-- bin
| |-- cyber_channel -> /opt/apollo/neo/packages/cyber-dev/latest/bin/cyber_channel
...
| |-- mainboard -> /opt/apollo/neo/packages/cyber-dev/latest/bin/mainboard
| `-- mainboard.py -> /opt/apollo/neo/packages/buildtool-dev/latest/bin/mainboard.py
|-- conf
|-- dag
|-- data
| |-- bag
| |-- core
| `-- log
|-- include
| |-- adapters -> /opt/apollo/neo/packages/common-dev/latest/include/adapters
...
| `-- vehicle_state -> /opt/apollo/neo/packages/common-dev/latest/include/vehicle_state
|-- launch
|-- lib
| |-- 3rd-fastrtps-dev -> /opt/apollo/neo/packages/3rd-fastrtps-dev/latest/lib
...
| `-- cyber-dev -> /opt/apollo/neo/packages/cyber-dev/latest/lib
|-- packages
| |-- 3rd-fastrtps-dev
| | |-- 1.0.0.1
| | `-- latest -> /opt/apollo/neo/packages/3rd-fastrtps-dev/1.0.0.1
...
| |-- cyber -> /opt/apollo/neo/packages/cyber-dev/latest
| `-- cyber-dev
| |-- 1.0.0.1
| `-- latest -> /opt/apollo/neo/packages/cyber-dev/1.0.0.1
|-- setup.sh -> /opt/apollo/neo/packages/buildtool-dev/latest/setup.sh
|-- share
`-- update_dylib.sh -> /opt/apollo/neo/packages/buildtool-dev/latest/scripts/update_dylib.sh
- bin directory: executable file unified entry, the software that stores executable files, the specific target is distributed within each package.
- conf directory: configuration file (reserved directory).
- dag directory: (reserved directory).
- data directory: data files (reserved directory).
- include directory: dependency package header file summary directory, through the software of the way each package include directory (or a level of subdirectory) link to the directory, need to pay attention to the name of the self-built dependency package, the way the same name conflict.
- launch directory: (reserved directory).
- lib directory: the unified entrance of dynamic SO, the lib directory of each package is linked to this directory by means of a soft chain.
- packages directory: the actual storage directory of packages.
- Each subdirectory is a package, and the different versions in the packages directory are stored separately using the version number, while using the latest softlink to link to the latest installed (or compiled) version. It is recommended to use the latest version directly, so that you can use the latest version.
- share directory: (reserved directory).
- setup.sh file: set environment variables.
- update_dylib.sh file: update the system dynamic libraries, add apollo packages to the system libraries.