How can I print the version of libssl and libnspr in c++ code ?
I want to print version for both defined in header and library .
The header file opensslv.h #define 's the macro variable OPENSSL_VERSION_TEXT, describing the version. For instance "OpenSSL 0.9.8o-fips 01 Jun 2010".
For the library itself, the name of the lib file contains the version number. In ubuntu, in the folder /lib/, the file is called libssl.so.0.9.8. If you felt like it, you could use boost::filesystem to grab the particular filename and then parse it, perhaps using boost::regex.
Related
I'm compiling Linux libraries (for Android, using NDK's g++, but I bet my question makes sense for any Linux system). When delivering those libraries to partners, I need to mark them with a version number. I must also be able to access the version number programatically (to show it in an "About" dialog or a GetVersion function for instance).
I first compile the libraries with an unversioned flag (version 0.0) and need to change this version to a real one when I'm done testing just before sending it to the partner. I know it would be easier to modify the source and recompile, but we don't want to do that (because we should then test everything again if we recompile the code, we feel like it would be less error prone, see comments to this post and finally because our development environment works this way: we do this process for Windows binaries: we set a 0.0 resources version string (.rc) and we later change it by using verpatch...we'd like to work with the same kind of process when shipping Linux binaries).
What would be the best strategy here?
To summarize, requirements are:
Compile binaries with "unset" version (0.0 or anything else)
Be able to modify this "unset" version to a specific one without having to recompile the binary (ideally, run a 3rd party tool command, as we do with verpatch under Windows)
Be able to have the library code retrieve it's version information at runtime
If your answer is "rename the .so", then please provide a solution for 3.: how to retrieve version name (i.e.: file name) at runtime.
I was thinking of some solutions but have no idea if they could work and how to achieve them.
Have a version variable (one string or 3 int) in the code and have a way to change it in the binary file later? Using a binary sed...?
Have a version variable within a resource and have a way to change it in the binary file later? (as we do for win32/win64)
Use a field of the .so (like SONAME) dedicated to this and have a tool allowing to change it...and make it accessible from C++ code.
Rename the lib + change SONAME (did not find how this can be achieved)...and find a way to retrieve it from C++ code.
...
Note that we use QtCreator to compile the Android .so files, but they may not rely on Qt. So using Qt resources is not an ideal solution.
I am afraid you started to solve your problem from the end. First of all SONAME is provided at link time as a parameter of linker, so in the beginning you need to find a way to get version from source and pass to the linker. One of the possible solutions - use ident utility and supply a version string in your binary, for example:
const char version[] = "$Revision:1.2$"
this string should appear in binary and ident utility will detect it. Or you can parse source file directly with grep or something alike instead. If there is possibility of conflicts put additional marker, that you can use later to detect this string, for example:
const char version[] = "VERSION_1.2_VERSION"
So you detect version number either from source file or from .o file and just pass it to linker. This should work.
As for debug version to have version 0.0 it is easy - just avoid detection when you build debug and just use 0.0 as version unconditionally.
For 3rd party build system I would recommend to use cmake, but this is just my personal preference. Solution can be easily implemented in standard Makefile as well. I am not sure about qmake though.
Discussion with Slava made me realize that any const char* was actually visible in the binary file and could then be easily patched to anything else.
So here is a nice way to fix my own problem:
Create a library with:
a definition of const char version[] = "VERSIONSTRING:00000.00000.00000.00000"; (we need it long enough as we can later safely modify the binary file content but not extend it...)
a GetVersion function that would clean the version variable above (remove VERSIONSTRING: and useless 0). It would return:
0.0 if version is VERSIONSTRING:00000.00000.00000.00000
2.3 if version is VERSIONSTRING:00002.00003.00000.00000
2.3.40 if version is VERSIONSTRING:00002.00003.00040.00000
...
Compile the library, let's name it mylib.so
Load it from a program, ask its version (call GetVersion), it returns 0.0, no surprise
Create a little program (did it in C++, but could be done in Python or any other languauge) that will:
load a whole binary file content in memory (using std::fstream with std::ios_base::binary)
find VERSIONSTRING:00000.00000.00000.00000 in it
confirms it appears once only (to be sure we don't modify something we did not mean to, that's why I prefix the string with VERSIONSTRING, to make it more unic...)
patch it to VERSIONSTRING:00002.00003.00040.00000 if expected binary number is 2.3.40
save the binary file back from patched content
Patch mylib.so using the above tool (requesting version 2.3 for instance)
Run the same program as step 3., it now reports 2.3!
No recompilation nor linking, you patched the binary version!
I am using a header library in my code to set my output directory. I would be running almost 12000 executables in parallel and I want a common output folder which is one level up. Here is how I use it
global::directories().setOutputDir("./outputfolder/");
where outputfolder is a folder in the current directory with the executable. I would like this string to be one folder up directory (somethong like ../outputfolder)
Unfortunately setOutputDir takes inputs as string (http://www.palabos.org/documentation/develguide/globalDefs_8h_source.html)
I looked around and found that boost library would be the most appropriate way to achieve what I want. Just wanted to know if there can be a workaround using the standard C++ before I delve into the library
Thanks..
I have a library and I have generated tcl bindings for the same using swig. The dll thus generated is xyz_tcl.dll if my original lib dll us xyz.dll. but when I try to load the dll its says "invalid command name "MZ"". Can any one tell me what could be reason for it.
The MZ is almost certainly the first few bytes of the DLL (it's the “magic number” of the file format) so at a guess you're trying to do:
source xyz_tcl.dll
That won't work. It contains compiled C code that integrates with Tcl, but not a Tcl script. Instead, you need to do:
load xyz_tcl.dll
Of course, it should be build into a package (which is a directory containing the required DLLs and a file pkgIndex.tcl) which would then let you do something like this instead:
package require xyz
(The pkgIndex.tcl file contains instructions on how to define the package using the other files, through load and source as necessary.)
I think that something (tcl?) is trying to execute the DLL as a script - the first two bytes of a Windows executable file are 'M' and 'Z'.
For historical reasons, every Win32 executable has a small 16-bit MS-DOS header just before the actual Win32 PE header, and the signature bytes for the 16-bit header are "MZ".
I am very new to R. I would like to build an R package which will call a C++ function using .Call().
I have a NAMESPACE file, with
useDynLib(mypkg)
where mypkg is also the function name of my c++ code.
It works if I use this line at the begining of the mypkg.R file:
dyn.load("src/mypkg.so")
but I want to use library.dynam instead, so in the zzz.R file, I put
.onLoad<-function(libname, pkgname)
{
library.dynam("mypkg", pkgname, libname)
}
It gives the error when checking the package:
...
Error in .Call("mypkg", PACKAGE = "mypkg") :
C symbol name "mypkg" not in DLL for package "mypkg".
Error : unable to load R code in package 'mypkg'
...
It looks like the *.so file is generated in the wrong place? Why there is not /libs folder generated?
I would like to build the package to be os independent, is there a way to do it with dyn.load?
And this may be a very silly question, where did pkgname and libname get their input from?
Thank you very much for your help.
You could look at one of the many existing packages (with compiled source code) on CRAN.
Smaller and simpler is easier to grok, so you could e.g. look at digest which uses a NAMESPACE to load the one shared library built from the handful of C source files, and uses .Call() to access the main entry point.
And then there is of course the manual...
Hello now i try translate project on other platform(first platform it's windows, now company planed use Linux platform), i use eclipse in windows and Linux, language is c++. Name project PostLib and he have next structure: PostLib/common, PostLib/inc, PostLib/inc_ext, PostLib/src.
PostLib/common its part for control memory leaks and for smart pointer. PostLib/inc PostLib/inc_ext - this part for header, and PostLib/src for sources code.My problem next: In project settings, i use PostLib/common, PostLib/inc and PostLib/inc_ext, and Eclipse write error: File Def.h(PostLib/inc_ext) can not find file p_mem.h(PostLib/common). How can it be?
When i look property all direction in project i saw interesting thing: Property on directory PostLib/inc_ext difference than all project, on other directory property same like in project/ Property i mean Property->Settings->GCC C++ Compiler->Directories, i try add path (PostLib/common) , but no effect, Eclipse write error File Def.h(PostLib/inc_ext) can not find file p_mem.h(PostLib/common).
On Linux systems directory separator is /, not \!
PostLib\common\p_mem.h is a path in windows, but is not in Linux. The equivalent for Linux is PostLib/common/p_mem.h.
Also, filesystem paths on Linux are case sensitive. p_mem.h is a different file from P_Mem.h: be sure you used the right characters for files and directories.