Skip to content

Commit

Permalink
fix(update): grpc generators update
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrienSchadle committed Jun 12, 2023
1 parent 89aa1c2 commit ef13dc9
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 92 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Expand Up @@ -6,4 +6,4 @@
url = https://github.com/mariusbancila/stduuid.git
[submodule "libs/cppast"]
path = libs/cppast
url = https://github.com/Firefly35/cppast.git
url = https://github.com/foonathan/cppast.git
6 changes: 3 additions & 3 deletions libs/build_cppast.sh
Expand Up @@ -5,11 +5,11 @@ BUILDFOLDER=build-cppast
LLVMBREWPATH=/usr/local
TARGETPLATFORM=mac-clang
if [[ "$OSTYPE" == "linux-gnu" ]]; then
sudo apt-get install -y llvm-10 clang-10 libclang-10-dev
sudo apt-get install -y llvm-15 clang-15 libclang-15-dev
LLVMBREWPATH=/home/linuxbrew/.linuxbrew
LLVMCONFIGPATH=/usr/bin/llvm-config-10
LLVMCONFIGPATH=/usr/bin/llvm-config-15
TARGETPLATFORM=linux-gcc
CPPASTCMAKECOMPILER="-DCMAKE_CXX_COMPILER=clang++-10"
CPPASTCMAKECOMPILER="-DCMAKE_CXX_COMPILER=clang++-15"
if test ! $(which brew); then
echo "brew is not installed, first install brew then relaunch this script\n";
exit 1
Expand Down
2 changes: 1 addition & 1 deletion libs/cppast
2 changes: 1 addition & 1 deletion packagedependencies-linux.txt
@@ -1,2 +1,2 @@
boost#stable|1.78.0|boost|conan|conan-center|default|
grpc|1.37.1|grpc++%WITHREMOTING|http|https://github.com/b-com-software-basis/thirdparties-binaries/releases/download
grpc|1.50.1|grpc++%WITHREMOTING|conan|conancenter
2 changes: 1 addition & 1 deletion packagedependencies-win.txt
@@ -1,2 +1,2 @@
boost#stable|1.78.0|boost|conan|conan-center|default|
grpc|1.37.1|grpc++%WITHREMOTING|http|https://github.com/b-com-software-basis/thirdparties-binaries/releases/download|static
grpc|1.37.1|grpc++%WITHREMOTING|conan|conancenter|
115 changes: 53 additions & 62 deletions src/Factory.cpp
Expand Up @@ -871,6 +871,7 @@ FactoryBindInfos Factory::resolveBind(const uuids::uuid & interfaceUUID, const s
!(contextLevels.back().second.bindingRangeMask & (BindingRange::Default|BindingRange::All))) {
throw InjectableNotFoundException("No default named binding found to resolve component from interface UUID = " + uuids::to_string(interfaceUUID) + " named " + name);
}

return resolveBind(interfaceUUID, contextLevels);
}

Expand Down Expand Up @@ -909,87 +910,77 @@ void Factory::inject(SRef<IInjectable> component, std::deque<BindContext> contex
}
}
catch (const Exception& e) {
throw ConfigurationException(e.what());
if (!injectable->optional()) { // only throw when injectable is mandatory
throw ConfigurationException(e.what());
}
}
}
component->onInjected();
}

SRef<IComponentIntrospect> Factory::resolveComponent(const FactoryBindInfos & bindInfos, std::deque<BindContext> contextLevels)
{
try
{
uuids::uuid componentUUID = bindInfos.componentUUID;
std::function<SRef<IComponentIntrospect>(void)> createComponent = [componentUUID, this]()-> SRef<IComponentIntrospect> {
return resolveFromModule(componentUUID);
};
uuids::uuid componentUUID = bindInfos.componentUUID;
std::function<SRef<IComponentIntrospect>(void)> createComponent = [componentUUID, this]()-> SRef<IComponentIntrospect> {
return resolveFromModule(componentUUID);
};

if (mapContains(m_context->factoryMethods, componentUUID)) {
createComponent = m_context->factoryMethods[componentUUID];
}
if (bindInfos.bindingRangeMask == BindingRange_Core) {
createComponent = m_coreFactoryMethods[componentUUID];
}
#ifdef XPCF_WITH_LOGS
BOOST_LOG_SEV(m_logger, logging::trivial::info)<<"Factory::resolveComponent component uuid="<<uuids::to_string(componentUUID);
#endif
SRef<IComponentIntrospect> componentRef = createComponent();
inject(componentRef->bindTo<IInjectable>(), contextLevels);
if (componentRef->implements<IConfigurable>()) {
fs::path configFilePath = m_propertyManager->getConfigPath(componentUUID);
if (! configFilePath.empty()) {
SRef<IConfigurable> iconf = componentRef->bindTo<IConfigurable>();
XPCFErrorCode confErrCode;
if (bindInfos.properties.empty()) {
confErrCode = iconf->configure(configFilePath.string().c_str());
}
else {
confErrCode = iconf->configure(configFilePath.string().c_str(), bindInfos.properties.c_str());
}
if (confErrCode != XPCFErrorCode::_SUCCESS) {
throw ConfigurationException("Configuration failed for component uuid=" + uuids::to_string(componentUUID), confErrCode);
}
if (mapContains(m_context->factoryMethods, componentUUID)) {
createComponent = m_context->factoryMethods[componentUUID];
}
if (bindInfos.bindingRangeMask == BindingRange_Core) {
createComponent = m_coreFactoryMethods[componentUUID];
}
#ifdef XPCF_WITH_LOGS
BOOST_LOG_SEV(m_logger, logging::trivial::info)<<"Factory::resolveComponent component uuid="<<uuids::to_string(componentUUID);
#endif
SRef<IComponentIntrospect> componentRef = createComponent();
inject(componentRef->bindTo<IInjectable>(), contextLevels);
if (componentRef->implements<IConfigurable>()) {
fs::path configFilePath = m_propertyManager->getConfigPath(componentUUID);
if (! configFilePath.empty()) {
SRef<IConfigurable> iconf = componentRef->bindTo<IConfigurable>();
XPCFErrorCode confErrCode;
if (bindInfos.properties.empty()) {
confErrCode = iconf->configure(configFilePath.string().c_str());
}
else {
confErrCode = iconf->configure(configFilePath.string().c_str(), bindInfos.properties.c_str());
}
if (confErrCode != XPCFErrorCode::_SUCCESS) {
throw ConfigurationException("Configuration failed for component uuid=" + uuids::to_string(componentUUID), confErrCode);
}
}
return componentRef;
}
catch (const bcom::xpcf::Exception& e) {
throw ConfigurationException(e.what());
}
return componentRef;
}

SRef<IComponentIntrospect> Factory::resolve(const uuids::uuid & interfaceUUID, std::deque<BindContext> contextLevels)
{
try
{
FactoryBindInfos bindInfos = resolveBind(interfaceUUID, contextLevels);
#ifdef XPCF_WITH_LOGS
BOOST_LOG_SEV(m_logger, logging::trivial::info)<<"Factory::resolve interface uuid="<<uuids::to_string(interfaceUUID);
BOOST_LOG_SEV(m_logger, logging::trivial::info)<<log(bindInfos).str();
#endif
contextLevels.push_front({ContextType::Component, bindInfos});
if (bindInfos.scope == BindingScope::Singleton) {
if (bindInfos.bindingRangeMask != BindingRange_Core) {
if (! mapContains(m_singletonInstances, bindInfos.componentUUID)) {
SRef<IComponentIntrospect> componentRef = resolveComponent(bindInfos, contextLevels);
m_singletonInstances[bindInfos.componentUUID] = componentRef;
}
return m_singletonInstances.at(bindInfos.componentUUID);
FactoryBindInfos bindInfos = resolveBind(interfaceUUID, contextLevels);
#ifdef XPCF_WITH_LOGS
BOOST_LOG_SEV(m_logger, logging::trivial::info)<<"Factory::resolve interface uuid="<<uuids::to_string(interfaceUUID);
BOOST_LOG_SEV(m_logger, logging::trivial::info)<<log(bindInfos).str();
#endif
contextLevels.push_front({ContextType::Component, bindInfos});
if (bindInfos.scope == BindingScope::Singleton) {
if (bindInfos.bindingRangeMask != BindingRange_Core) {
if (! mapContains(m_singletonInstances, bindInfos.componentUUID)) {
SRef<IComponentIntrospect> componentRef = resolveComponent(bindInfos, contextLevels);
m_singletonInstances[bindInfos.componentUUID] = componentRef;
}
else {
if (! mapContains(m_coreInstances, bindInfos.componentUUID)) {
SRef<IComponentIntrospect> componentRef = resolveComponent(bindInfos, contextLevels);
m_coreInstances[bindInfos.componentUUID] = componentRef;
}
return m_coreInstances.at(bindInfos.componentUUID);
return m_singletonInstances.at(bindInfos.componentUUID);
}
else {
if (! mapContains(m_coreInstances, bindInfos.componentUUID)) {
SRef<IComponentIntrospect> componentRef = resolveComponent(bindInfos, contextLevels);
m_coreInstances[bindInfos.componentUUID] = componentRef;
}
return m_coreInstances.at(bindInfos.componentUUID);
}
SRef<IComponentIntrospect> componentRef = resolveComponent(bindInfos, contextLevels);
return resolveComponent(bindInfos, contextLevels);
}
catch ( const bcom::xpcf::Exception& e) {
throw ConfigurationException(e.what());
}
SRef<IComponentIntrospect> componentRef = resolveComponent(bindInfos, contextLevels);
return resolveComponent(bindInfos, contextLevels);
}

SRef<IComponentIntrospect> Factory::resolve(const uuids::uuid & interfaceUUID, const string & name, std::deque<BindContext> contextLevels )
Expand Down
101 changes: 85 additions & 16 deletions tools/generators/grpc/GRPCProtoGenerator.cpp
Expand Up @@ -89,6 +89,7 @@ static const std::map<std::string,std::string> protoReservedKeywordsTranscriptio

GRPCProtoGenerator::GRPCProtoGenerator():AbstractGenerator(xpcf::toMap<GRPCProtoGenerator>())
{

}


Expand Down Expand Up @@ -290,40 +291,107 @@ std::map<IRPCGenerator::MetadataType,std::string> GRPCProtoGenerator::generateIm
return metadata;
}

std::string getPackageId(bp::ipstream& packageDescription)
{
std::string result="";
std::string line="";

bool bFound=false;
std::getline(packageDescription, line);
while(!bFound){
size_t pos = line.find("Package_ID: ");
if(pos != std::string::npos) {
result=line.substr(pos+12, line.find_last_of('\n'));
bFound=true;
} else {
std::getline(packageDescription, line);
}
}
return result;
}

std::string getRequiredPackageId(std::string requiredPackageName, bp::ipstream& packageDescription)
{
std::string result="";
std::string line="";

// Find "[requires]" part
bool bFound=false;
std::getline(packageDescription, line);
while(!bFound && !packageDescription.eof()){
size_t pos = line.find("[requires]");
if(pos != std::string::npos) {
bFound=true;
} else {
std::getline(packageDescription, line);
}
}

// Find required package name <requiredPackageName>/<packageVersion>:<packageId>\n
bFound=false;
while(!bFound && !packageDescription.eof()){
size_t pos = line.find(requiredPackageName);
if(pos != std::string::npos) {
result=line.substr(line.find_last_of(':')+1, line.find_last_of('\n'));
bFound=true;
} else {
std::getline(packageDescription, line);
}
}

return result;
}

void GRPCProtoGenerator::finalizeImpl(std::map<MetadataType,std::string> metadata)
{
fs::path remakenGrpcRoot = RemakenPathHelper::computeRemakenRootPackageDir();
std::vector<fs::path> envPath = boost::this_process::path();
remakenGrpcRoot /= "grpc/1.37.1";
fs::path grpcBin = remakenGrpcRoot;
grpcBin /= "/bin/x86_64/shared/release/";
fs::path grpcLibs = remakenGrpcRoot;
grpcLibs /= "/lib/x86_64/shared/release/";
fs::path remakenGrpcRoot = RemakenPathHelper::computeRemakenRootPackageDir();

bp::ipstream out;
bp::system("conan search grpc/1.50.1@ -q \"build_type=Release AND shared=False\"", bp::std_out > out);
std::string grpcPackageId = getPackageId(out);
std::string protobufPackageId = getRequiredPackageId("protobuf", out);

fs::path conanDataPath = RemakenPathHelper::getHomePath();
conanDataPath /= ".conan/data/";
fs::path grpcLibs = conanDataPath;
grpcLibs /= "grpc/1.50.1/_/_/package/";
grpcLibs /= grpcPackageId;
grpcLibs /= "/lib/";
fs::path grpcBin = conanDataPath;
grpcBin /= "grpc/1.50.1/_/_/package/";
grpcBin /= grpcPackageId;
grpcBin /= "/bin/";
fs::path protocBin = conanDataPath;
protocBin /= "protobuf/3.21.9/_/_/package/";
protocBin /= protobufPackageId;
protocBin /= "/bin/";
std::string SharedLibraryPathEnvName(RemakenPathHelper::sharedLibraryPathEnvName());

auto env = boost::this_process::environment();
bp::environment runEnv = env;
fs::detail::utf8_codecvt_facet utf8;
std::cout << "Searching protobuf compiler (protoc) from path: " << std::endl;
std::cout << "===> "<< grpcBin.generic_string(utf8) << std::endl;
std::cout << "===> "<< protocBin.generic_string(utf8) << std::endl;

bool isRemakenGrpc = true;
if (!fs::exists(grpcBin) || !fs::exists(grpcLibs)) {
if (!fs::exists(protocBin) || !fs::exists(grpcLibs) || !fs::exists(grpcBin)) {
isRemakenGrpc = false;
// else search in brew paths on unixes, what about win ?
// else search in brew paths on unixes, what about win ?
#ifdef BOOST_OS_MACOS_AVAILABLE
grpcBin = "/usr/local/bin/";
grpcLibs = "/usr/local/lib";
protocBin = "/usr/local/bin/";
grpcLibs = "/usr/local/lib";
#endif
#ifdef BOOST_OS_LINUX_AVAILABLE
grpcBin = "/home/linuxbrew/.linuxbrew/bin/";
grpcLibs = "/home/linuxbrew/.linuxbrew/lib";
protocBin = "/home/linuxbrew/.linuxbrew/bin/";
grpcLibs = "/home/linuxbrew/.linuxbrew/lib";
#endif
#ifdef BOOST_OS_WIN_AVAILABLE
std::cerr<<"Error grpc protoc compiler not found : check your grpc installation !"<<std::endl;
return;
std::cerr<<"Error grpc protoc compiler not found : check your grpc installation !"<<std::endl;
return;
#endif
}
envPath.push_back(protocBin);
envPath.push_back(grpcBin);
runEnv[SharedLibraryPathEnvName] += grpcLibs.generic_string(utf8);
fs::path toolPath = bp::search_path("protoc", envPath);
Expand All @@ -337,9 +405,10 @@ void GRPCProtoGenerator::finalizeImpl(std::map<MetadataType,std::string> metadat
return;
}
std::cout << "Using protobuf compiler (protoc) from path: " << std::endl;
std::cout << "===> "<< grpcBin.generic_string(utf8) << std::endl;
std::cout << "===> "<< protocBin.generic_string(utf8) << std::endl;

int result = -1;
std::cout << "m_protoNameFilesPathMap.size()=" << m_protoNameFilesPathMap.size() << std::endl;
for (auto [name, protoFile] : m_protoNameFilesPathMap) {
std::cout << "generating grpc service and messages for " << name << " from .proto "<< protoFile.generic_string(utf8) << std::endl;
std::string protoPath = "--proto_path=";
Expand Down
1 change: 1 addition & 0 deletions tools/generators/grpc/RemakenPathHelper.cpp
Expand Up @@ -7,6 +7,7 @@
#include <stdlib.h>
#else
#include <pwd.h>
#include <map>
#include <sys/types.h>
#endif

Expand Down
3 changes: 2 additions & 1 deletion tools/generators/grpc/packagedependencies.txt
@@ -1 +1,2 @@
xpcf|2.6.3|xpcf|github|https://github.com/b-com-software-basis/xpcf/releases/download
xpcf|2.7.0|xpcf|github|https://github.com/b-com-software-basis/xpcf/releases/download
grpc|1.50.1|grpc%WITHREMOTING|conan|conancenter
9 changes: 7 additions & 2 deletions tools/generators/grpc/xpcf_grpc_gen.cpp
Expand Up @@ -35,6 +35,7 @@
#include <cppast/cpp_array_type.hpp>
#include "ClassDescriptor.h"
#include <xpcf/api/IComponentManager.h>
#include <xpcf/core/Exception.h>
#include <xpcf/core/helpers.h>
#include "RemoteServiceGenerator.h"
#include "GRPCProtoGenerator.h"
Expand Down Expand Up @@ -94,6 +95,7 @@ SRef<xpcf::IComponentManager> bindXpcfComponents() {
cmpMgr->bindLocal<IRPCGenerator, ServerGenerator>("server");
cmpMgr->bindLocal<IRPCGenerator, ProjectGenerator>("project");
#else

// chained injection through base class composite approach :
cmpMgr->bindLocal<IRPCGenerator, RemoteServiceGenerator, xpcf::BindingScope::Singleton, xpcf::BindingRange::Named|xpcf::BindingRange::Explicit>("service");
cmpMgr->bindLocal<GRPCProtoGenerator, IRPCGenerator, ProxyGenerator, xpcf::BindingScope::Transient, xpcf::BindingRange::Explicit|xpcf::BindingRange::Default>();
Expand Down Expand Up @@ -243,6 +245,7 @@ try
if (result != 0)
return result;
}

//update types : try to qualify non fqdn types in parameters ... from classes found during parsing
for (auto & [name,c] : astParser->getParsedInterfaces()) {
for (auto & m: c->methods()) {
Expand Down Expand Up @@ -282,11 +285,13 @@ try
}
serviceGenerator->finalize(astParser->metadata());
}


}
catch (const cppast::libclang_error& ex)
{
print_error(std::string("[fatal parsing error] ") + ex.what());
return 2;
}
catch (org::bcom::xpcf::Exception e)
{
std::cout << "Xpcf exception: " << e.what() << std::endl;
}
8 changes: 4 additions & 4 deletions tools/generators/grpc/xpcf_grpc_gen.pro
Expand Up @@ -98,8 +98,8 @@ linux {
QMAKE_CXXFLAGS += -fPIC
# LLVM_BINARIES = /home/linuxbrew/.linuxbrew/opt/llvm/bin
LLVM_BINARIES = /usr/bin
LLVM_LIBDIR = $$system($${LLVM_BINARIES}/llvm-config-10 --libdir)
LLVM_INCDIR = $$system($${LLVM_BINARIES}/llvm-config-10 --includedir)
LLVM_LIBDIR = $$system($${LLVM_BINARIES}/llvm-config-15 --libdir)
LLVM_INCDIR = $$system($${LLVM_BINARIES}/llvm-config-15 --includedir)
LIBS += -L$${LLVM_LIBDIR} -lclang
LLVM_CLANG_LIBS = $$files($${LLVM_LIBDIR}/libclang*.a)
LIBS += $${LLVM_CLANG_LIBS}
Expand Down Expand Up @@ -135,8 +135,8 @@ win32 {
# DEFINES += WIN64 UNICODE _UNICODE
QMAKE_COMPILER_DEFINES += _WIN64

LLVM_LIBDIR = $$system(llvm-config --libdir)
LLVM_INCDIR = $$system(llvm-config --includedir)
LLVM_LIBDIR = $$system(llvm-config.exe --libdir)
LLVM_INCDIR = $$system(llvm-config.exe --includedir)
LIBS += -L\"$${LLVM_LIBDIR}\" -llibclang -lShell32
# QMAKE_LFLAGS += -L\"$${LLVM_LIBDIR}\"
QMAKE_CXXFLAGS += -I\"$${LLVM_INCDIR}\"
Expand Down

0 comments on commit ef13dc9

Please sign in to comment.