PhoenixHPCProxy  0.8.0
Lightweight HPC proxy
Loading...
Searching...
No Matches
backend.cpp
Go to the documentation of this file.
1/***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5****************************************/
6
7#include "backend.h"
8
10
13 PString body("");
14 body += "/***************************************\n";
15 body += "\tAuteur : Pierre Aubert\n";
16 body += "\tMail : pierre.aubert@lapp.in2p3.fr\n";
17 body += "\tLicence : CeCILL-C\n";
18 body += "****************************************/\n\n\n";
19
20 body += "//Warning : this file has been generated automatically by the phoenix_hpc_proxy program\n";
21 body += "//You can find it at https://gitlab.in2p3.fr/CTA-LAPP/PHOENIX_LIBS/PhoenixHPCProxy\n";
22 body += "//Do NOT modify it\n\n\n";
23 return body;
24}
25
27
30PString getHandleFunction(const PString & functionName){
31 return "handle_" + functionName;
32}
33
35
38PString getHandleFunctionType(const PString & functionName){
39 return "FunctionTypehandle_" + functionName;
40}
41
43
46PString getUpdateFunction(const PPath & fileName){
47 return "update_" + fileName.eraseExtension();
48}
49
51
55 if(function.getOtherCode() != ""){return function.getOtherCode();}
56 PString body("");
57 if(function.getDocString() != ""){body += function.getDocString();}
58 if(function.getTemplateDef() != ""){body += function.getTemplateDef();}
59 body += "inline " + function.getOutputType() + " " + function.getName() + "(";
60 bool isComma(false);
61 PVecArgument & vecArg = function.getVecArgument();
62 for(PVecArgument::iterator it(vecArg.begin()); it != vecArg.end(); ++it){
63 if(isComma){body += ", ";}
64 body += it->getType() + " ";
65 if(it->getPtrRef() != ""){body += it->getPtrRef() + " ";}
66 body += it->getName();
67 if(it->getDefaultValue() != ""){body += " = " + it->getDefaultValue();}
68 isComma = true;
69 }
70 body += "){\n";
71 isComma = false;
72 body += "\t"+getHandleFunction(function.getName())+"(";
73 for(PVecArgument::iterator it(vecArg.begin()); it != vecArg.end(); ++it){
74 if(isComma){body += ", ";}
75 body += it->getName();
76 isComma = true;
77 }
78 body += ");\n";
79 body += "}\n\n";
80 return body;
81}
82
84
88 if(!repr_isFunction(function)){return "";}
89 PString body("");
90 body += "typedef " + function.getOutputType() + "(*" + getHandleFunctionType(function.getName()) + ")(";
91 bool isComma(false);
92 PVecArgument & vecArg = function.getVecArgument();
93 for(PVecArgument::iterator it(vecArg.begin()); it != vecArg.end(); ++it){
94 if(isComma){body += ", ";}
95 body += it->getType();
96 if(it->getPtrRef() != ""){body += " " + it->getPtrRef();}
97 isComma = true;
98 }
99 body += ");\n";
100 return body;
101}
102
104
107PString cpp_backendHeader(PSource & source){
108 PString body(cpp_licenceSaveStr());
109 PString baseMacro("__" + source.getName().eraseExtension().toUpper() + "_PROXY_H__");
110 body += "#ifndef " + baseMacro + "\n";
111 body += "#define " + baseMacro + "\n\n";
112 body += "#include <iostream>\n\n\n";
113 PVecFunction & vecFunction = source.getVecFunction();
114 for(PVecFunction::iterator it(vecFunction.begin()); it != vecFunction.end(); ++it){
116 }
117 body += "\n\n";
118 for(PVecFunction::iterator it(vecFunction.begin()); it != vecFunction.end(); ++it){
119 if(!repr_isFunction(*it)){continue;}
120 body += "extern " + getHandleFunctionType(it->getName()) + " " + getHandleFunction(it->getName()) + ";\n";
121 }
122 body += "\n\n";
123 for(PVecFunction::iterator it(vecFunction.begin()); it != vecFunction.end(); ++it){
124 body += cpp_backendTableHeaderInline(*it);
125 }
126 body += "void " + getUpdateFunction(source.getName()) + "(void * handle);\n\n";
127
128 body += "#endif\n\n";
129 return body;
130}
131
133
137PString getMangleFunctionName(const PString & libraryName, const PString & functionName){
138 if(libraryName == ""){return functionName;}
139 PPath outputTmpFile(".mangledFunctionName.txt");
140 PString command("objdump --syms "+libraryName+" | grep \".text\" | sed -e \"s/ /\\n/g\" | grep "+functionName+" | head -n 1 > "+outputTmpFile);
141 if(system(command.c_str()) != 0){
142 return functionName;
143 }
144 PString fullFileContent(outputTmpFile.loadFileContent());
145 std::cerr << "getMangleFunctionName : full file content mangle function '"<<functionName<<"' : " << fullFileContent << std::endl;
146 PString mangleFunction(fullFileContent.eraseChar("\n\t "));
147 if(remove(outputTmpFile.c_str()) != 0){
148 std::cerr << "DPS::LibraryHandle::mangleFunctionName : cannot remove file '"<<outputTmpFile<<"'" << std::endl;
149 }
150 return mangleFunction;
151}
152
154
158PString cpp_backendSource(PSource & source, const PString & libName){
159 PString body(cpp_licenceSaveStr());
160 body += "#include <stdio.h>\n";
161 body += "#include <stdlib.h>\n";
162 body += "#include <dlfcn.h>\n\n";
163 body += "#include \""+source.getName().eraseExtension()+".h\"\n\n";
164
165 PVecFunction & vecFunction = source.getVecFunction();
166 for(PVecFunction::iterator it(vecFunction.begin()); it != vecFunction.end(); ++it){
167 if(!repr_isFunction(*it)){continue;}
168 body += getHandleFunctionType(it->getName()) + " " + getHandleFunction(it->getName()) + ";\n";
169 }
170 body += "\n\n";
171 body += "///Update the all the function handles of the file\n";
172 body += "/**\t@param handle : pointer to loaded library\n";
173 body += "*/\n";
174 body += "void " + getUpdateFunction(source.getName()) + "(void * handle){\n";
175 for(PVecFunction::iterator it(vecFunction.begin()); it != vecFunction.end(); ++it){
176 if(!repr_isFunction(*it)){continue;}
177 PString mangleFunction(getMangleFunctionName(libName, it->getName()));
178 body += "\t"+getHandleFunction(it->getName())+" = ("+getHandleFunctionType(it->getName())+")(dlsym(handle, \""+mangleFunction+"\"));\n";
179 }
180 body += "}\n\n";
181 return body;
182}
183
185
190bool cpp_backend(PSource & source, const PString & libName, const PPath & outputDir){
191 PString headerSrc(cpp_backendHeader(source));
192 PString sourceSrc(cpp_backendSource(source, libName));
193 PPath baseFileName(source.getName().eraseExtension());
194 PPath outputHeaderFile(outputDir / baseFileName + PString(".h"));
195 PPath outputSourceFile(outputDir / baseFileName + PString(".cpp"));
196 if(!outputHeaderFile.saveFileContent(headerSrc)){
197 std::cerr << "cpp_backend : cannot save header file '"<<outputHeaderFile<<"'" << std::endl;
198 return false;
199 }
200 std::cout << "cpp_backend : create header file '"<<outputHeaderFile<<"'" <<std::endl;
201 if(!outputSourceFile.saveFileContent(sourceSrc)){
202 std::cerr << "cpp_backend : cannot save source file '"<<outputSourceFile<<"'" << std::endl;
203 return false;
204 }
205 std::cout << "cpp_backend : create source file '"<<outputSourceFile<<"'" <<std::endl;
206 return true;
207}
208
210
215bool cpp_backend(PVecSource & vecSource, const PString & libName, const PPath & outputDir){
216 bool b(true);
217 for(PVecSource::iterator it(vecSource.begin()); it != vecSource.end(); ++it){
218 b &= cpp_backend(*it, libName, outputDir);
219 }
220 return b;
221}
222
PString cpp_licenceSaveStr()
Get the licence in string.
Definition backend.cpp:12
PString getHandleFunctionType(const PString &functionName)
Get the handle type name of the given function.
Definition backend.cpp:38
PString getMangleFunctionName(const PString &libraryName, const PString &functionName)
Get the mangled name of the given function name.
Definition backend.cpp:137
bool cpp_backend(PSource &source, const PString &libName, const PPath &outputDir)
Save a vector of PSource in the output directory.
Definition backend.cpp:190
PString getUpdateFunction(const PPath &fileName)
Get the update type name of the given file.
Definition backend.cpp:46
PString getHandleFunction(const PString &functionName)
Get the handle name of the given function.
Definition backend.cpp:30
PString cpp_backendTableHeaderInline(PFunction &function)
Save the function prototype as an inline function.
Definition backend.cpp:54
PString cpp_backendHeader(PSource &source)
Save the header of the given PSource.
Definition backend.cpp:107
PString cpp_backendTableHeaderHandleType(PFunction &function)
Save the function prototype as an inline function.
Definition backend.cpp:87
PString cpp_backendSource(PSource &source, const PString &libName)
Save the source of the given PSource.
Definition backend.cpp:158
Function prototype.
Definition PRepr.h:46
const PString & getName() const
Gets the name of the PFunction.
Definition PRepr.cpp:201
const PString & getDocString() const
Gets the docString of the PFunction.
Definition PRepr.cpp:215
const PString & getOutputType() const
Gets the outputType of the PFunction.
Definition PRepr.cpp:243
const PString & getOtherCode() const
Gets the otherCode of the PFunction.
Definition PRepr.cpp:271
const PString & getTemplateDef() const
Gets the templateDef of the PFunction.
Definition PRepr.cpp:257
const std::vector< PArgument > & getVecArgument() const
Gets the vecArgument of the PFunction.
Definition PRepr.cpp:229
Configuration file which will produce a source and header in C++.
Definition PRepr.h:88
const PPath & getName() const
Gets the name of the PSource.
Definition PRepr.cpp:337
const std::vector< PFunction > & getVecFunction() const
Gets the vecFunction of the PSource.
Definition PRepr.cpp:351
bool repr_isFunction(const PFunction &fct)
Say if the current function is a function prototype.
std::vector< PSource > PVecSource
std::vector< PArgument > PVecArgument
std::vector< PFunction > PVecFunction