[RFC] Canister Metadata Standard

We’re waiting on dfx extensions to do this in a very nice way automatically for the developer…we could do it sooner but we’re just focused on other things right now.

1 Like

Okay I think I’m going to add cdk:name to Azle in the next release, I’ll let you know how it goes.

@icpp does cdk:name work for you? For Azle it would be azle, for Kybra kybra, and for your project?

1 Like

What do you mean by dfx already having cdk:name? Does it?

@lastmjs

cdk:name will work and I will use icpp .

1 Like

@ZenVoich ,

Can you try it out on canister p5ezj-diaaa-aaaag-acn5a-cai ?
You can check on:

  • icp:public cdk:name → icpp
  • icp:public cdk:languages → c++
  • icp:private icpp:compiler → 3.14.1

@ZenVoich , @lastmjs

The command $ icpp build-wasm will now automatically add those custom sections to the wasm, using the already installed tool llvm-objcopy, which comes with wasi-sdk, which is what icpp-pro is build on top off.

In summary, with icpp-pro 3.14.1, the following commands are now run automatically as part of the build-wasm pipeline, and it works on Windows, Ubuntu and Mac:

--
Adding custom sections to the wasm file...
~/.icpp/wasi-sdk-20.0/bin/llvm-objcopy --add-section="icp:public candid:service"="/home/demo/greet/src/greet.did" greet.wasm greet.wasm
~/.icpp/wasi-sdk-20.0/bin/llvm-objcopy --add-section="icp:public cdk:name"="/home/demo/greet/build/custom_section_cdk_name.txt" greet.wasm greet.wasm
~/.icpp/wasi-sdk-20.0/bin/llvm-objcopy --add-section="icp:public cdk:languages"="/home/demo/greet/build/custom_section_cdk_languages.txt" greet.wasm greet.wasm
~/.icpp/wasi-sdk-20.0/bin/llvm-objcopy --add-section="icp:private icpp:compiler"="/home/demo/greet/build/custom_section_version.txt" greet.wasm greet.wasm
--

You can then verify the content of the custom sections using the llvm-objdump command:


# check 1
$ ~/.icpp/wasi-sdk-20.0/bin/llvm-objdump -h build/greet.wasm

build/greet.wasm:       file format wasm

Sections:
Idx Name                      Size     VMA      Type
Idx Name                      Size     VMA      Type
  0 TYPE                      0000013a 00000000 
  1 IMPORT                    000000d8 00000000 
  2 FUNCTION                  000008e9 00000000 
  3 TABLE                     00000007 00000000 
  4 MEMORY                    00000003 00000000 
  5 GLOBAL                    000006c3 00000000 
  6 EXPORT                    000047f1 00000000 
  7 ELEM                      00000869 00000000 
  8 CODE                      000b6ba4 00000000 TEXT
  9 DATA                      0000b21e 00000000 DATA
 10 icp:public candid:service 00000282 00000000 
 11 icp:public cdk:name       00000004 00000000 
 12 icp:public cdk:languages  00000003 00000000 
 13 icp:private icpp:compiler 00000006 00000000 

# With values for each section
$ ~/.icpp/wasi-sdk-20.0/bin/llvm-objdump --full-contents --section='icp:private icpp:compiler' build/greet.wasm

build/greet.wasm:       file format wasm
Contents of section icp:private icpp:compiler:
 0000 332e3133 2e30                        3.14.1

$ ~/.icpp/wasi-sdk-20.0/bin/llvm-objdump --full-contents --section='icp:public cdk:name' build/greet.wasm

build/greet.wasm:       file format wasm
Contents of section icp:public cdk:name:
 0000 69637070                             icpp

$ ~/.icpp/wasi-sdk-20.0/bin/llvm-objdump --full-contents --section='icp:public cdk:languages' build/greet.wasm
 
build/greet.wasm:       file format wasm
Contents of section icp:public cdk:languages:
 0000 632b2b                               c++

Reason I decided to go with this approach is because of what I saw in the motoko wasm:


# check 1
$ llvm-objdump -h my_motoko.wasm

my_motoko.wasm: file format wasm

Sections:
Idx Name                            Size     VMA      Type
  0 TYPE                            000000c8 00000000 
  1 IMPORT                          0000026f 00000000 
  2 FUNCTION                        00000378 00000000 
  3 TABLE                           00000007 00000000 
  4 MEMORY                          00000003 00000000 
  5 GLOBAL                          00000084 00000000 
  6 EXPORT                          000001d3 00000000 
  7 START                           00000002 00000000 
  8 ELEM                            0000077c 00000000 
  9 CODE                            00028e65 00000000 TEXT
 10 DATA                            00011541 00000000 DATA
 11 name                            0000661d 00000000 
 12 icp:public candid:service       0000047c 00000000 
 13 icp:private motoko:stable-types 0000004f 00000000 
 14 icp:private motoko:compiler     00000005 00000000 
 15 icp:public candid:args          00000009 00000000 

# Check 2
$ llvm-objdump --full-contents --section='icp:private motoko:compiler' my_motoko.wasm

my_motoko.wasm: file format wasm
Contents of section icp:private motoko:compiler:
 0000 302e392e 38                          0.9.8

After seeing what’s in the Motoko wasm, I decided to just do both, and I implemented @lastmjs suggestion for name & languagues, but then the motoko convention for version number.


ps. one great side effect of this effort is that I learned how to stuff the candid file into the wasm using llvm-objcopy, and when I deploy, the Candid UI now works!

:tada:


@lwshang ,

If dfx will support these metadatas as part of a standard, I will switch to that implementation for consistency.

3 Likes

Can’t wait to see the C++ canisters count listed on https://icp.zone/

At least 4 :smile:

3 Likes

Added support for C++ canisters

image

exactly 4)

5 Likes

Thanks for adding TypeScript! How up-to-date is the info? When does the process run?

To check the language of new canisters, I run it manually once a week or so

1 Like

Hi folks.

I just posted [RFC] tech_stack - Canister Metadata Standard extension.

It is my latest effort to cover the usage of cdk:* fields.

I’m looking forward to your feedback.

cc: @lastmjs @icpp @ZenVoich

2 Likes