PengZheng commented on issue #590: URL: https://github.com/apache/celix/issues/590#issuecomment-1966404599
The aim of descriptor generation for remote services is to make service header file the single source of truth. To this end, we need to be able to annotate service function argument (`am=pre`/`am=out`). I tried the following prototype and believe it could work: ```C //calculator_service.h #ifndef CALCULATOR_SERVICE_H_ #define CALCULATOR_SERVICE_H_ #define CALCULATOR_SERVICE "org.apache.celix.calc.api.Calculator" #define CALCULATOR_SERVICE_VERSION "1.3.0" #define CALCULATOR_CONFIGURATION_TYPE "org.amdatu.remote.admin.http, celix.remote.admin.shm" /* * The calculator service definition corresponds to the following Java interface: * * interface Calculator { * double add(double a, double b); * double sub(double a, double b); * double sqrt(double a); * } */ typedef struct [[clang::annotate("celix::services", CALCULATOR_SERVICE, CALCULATOR_SERVICE_VERSION)]] calculator_service { void *handle; int (*add)(void *handle, double a, double b, double *[[clang::annotate_type("celix::pre")]] result); int (*sub)(void *handle, double a, double b, double *[[clang::annotate_type("celix::pre")]] result); int (*sqrt)(void *handle, double a, double * [[clang::annotate_type("celix::pre")]] result); } calculator_service_t; #endif /* CALCULATOR_SERVICE_H_ */ ``` ```C // calculator_service.c #include "calculator_service.h" ``` Note that `calculator_service.cc` is only used for descriptor generation and thus is deliberately left empty. ```bash $ clang-15 -Xclang -ast-dump -fsyntax-only -std=c2x calculator_service.c TranslationUnitDecl 0x559464320ec8 <<invalid sloc>> <invalid sloc> |-TypedefDecl 0x5594643216f0 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128' | `-BuiltinType 0x559464321490 '__int128' |-TypedefDecl 0x559464321760 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128' | `-BuiltinType 0x5594643214b0 'unsigned __int128' |-TypedefDecl 0x559464321a68 <<invalid sloc>> <invalid sloc> implicit __NSConstantString 'struct __NSConstantString_tag' | `-RecordType 0x559464321840 'struct __NSConstantString_tag' | `-Record 0x5594643217b8 '__NSConstantString_tag' |-TypedefDecl 0x559464321b00 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *' | `-PointerType 0x559464321ac0 'char *' | `-BuiltinType 0x559464320f70 'char' |-TypedefDecl 0x559464321df8 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'struct __va_list_tag[1]' | `-ConstantArrayType 0x559464321da0 'struct __va_list_tag[1]' 1 | `-RecordType 0x559464321be0 'struct __va_list_tag' | `-Record 0x559464321b58 '__va_list_tag' |-RecordDecl 0x55946437c3a8 <./calculator_service.h:36:9, line:41:1> line:36:103 struct calculator_service definition | |-AnnotateAttr 0x55946437c450 <col:18, col:99> "celix::services" | | |-ConstantExpr 0x55946437c500 <line:23:41> 'char (*)[37]' | | | |-value: LValue <todo> | | | `-ImplicitCastExpr 0x55946437c4e8 <col:41> 'char (*)[37]' <ArrayToPointerDecay> | | | `-StringLiteral 0x55946437c308 <col:41> 'char[37]' lvalue "org.apache.celix.calc.api.Calculator" | | `-ConstantExpr 0x55946437c5a0 <line:24:41> 'char (*)[6]' | | |-value: LValue <todo> | | `-ImplicitCastExpr 0x55946437c588 <col:41> 'char (*)[6]' <ArrayToPointerDecay> | | `-StringLiteral 0x55946437c388 <col:41> 'char[6]' lvalue "1.3.0" | |-FieldDecl 0x55946437c648 <line:37:5, col:11> col:11 handle 'void *' | |-FieldDecl 0x55946437cb50 <line:38:5, col:103> col:11 add 'int (*)(void *, double, double, double * [[clang::annotate_type(...)]])' | |-FieldDecl 0x55946437ce90 <line:39:5, col:103> col:11 sub 'int (*)(void *, double, double, double * [[clang::annotate_type(...)]])' | `-FieldDecl 0x55946437d258 <line:40:5, col:95> col:11 sqrt 'int (*)(void *, double, double * [[clang::annotate_type(...)]])' `-TypedefDecl 0x559464383368 <line:36:1, line:41:3> col:3 calculator_service_t 'struct calculator_service':'struct calculator_service' `-ElaboratedType 0x559464383310 'struct calculator_service' sugar `-RecordType 0x55946437c430 'struct calculator_service' `-Record 0x55946437c3a8 'calculator_service' ``` `[[clang::annotate("celix::services")]]` serves two purposes: 1. Help the generator locate the root AST we are interested. 2. Pass service name and version to descriptor generator. We need `clang::annotate_type` to support per-argument annotation, which is not possible using `clang::annotate`. `clang::annotate_type` is a relatively new attribute supported by clang, which is ignored by older version of clang (like clang-14). To use it, we need either `-std=c++11` or `-std=c2x`. Here, I prefer to treat the service header as a C header rather than C++. Another downside of using `clang::annotate_type` is that it is not exposed by libclang, we need libTooling to finish our job. Rather than `pip install libclang` and let CMake call a python script, we need to: 1. Develop the generator in C++ based on libTooling. 2. Build the generator first before using it to generate descriptors. 3. Support cross compilation. In conan's terminology, the generator should be built in build context rather than host context. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@celix.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org