Compile a C++ code snippet using G++ dynamically - c++

Working on a C++ based application, it takes user input and generates a C++ function and compile it to create a .so file and links the function to the main application. Currently had to call an external command "g++" to do it. Wonder if it's possible to call some kind of function, say, "compile" which takes as input an code snippet and produces an .so. More precisely, I need a function that has the following syntax:
sizeOfObjBuf = compile(codeBuf, objBuf);
First parameter is a null terminated string containing a code snippet, the second parameter is the output buffer that hold the compiled code and it returns the size of size of compiled code.
The whole idea is to get rid of dependency on an external program (g++) so the application can run on any Linux system (even when it doesn't have g++ installed).
Thanks.

I'm afraid the answer is "no".

You could implement that function by executing G++ (or some other compiler) in a separate process and waiting for it to finish, but that still requires the user to have a compiler installed.
You can't compile C++ code without a C++ compiler.

I am not going to do the research to figure out how it is done, but I believe the LLVM C++ compiler can be used in this way. All of the parts of LLVM are designed to run as a library, in theory.
OK, a tiny bit of research and I found this: http://clang.llvm.org/docs/LibTooling.html

Related

"no main" function for linking or execution in C++ [duplicate]

This question already has answers here:
How to change entry point of C program with gcc?
(4 answers)
Closed 5 years ago.
I am trying to compile a function (not called main) that can be integrated in another code or directly executed (after linking).
I try it one my mac, and work well.
I finally test it on Linux (CentOS and ubuntu). However, the task looks harder as expected on Linux.
The source code is the following one (just to explain the problem)
test.cpp:
#include <cstdio>
#ifdef __cplusplus
extern "C" {
#endif
int test(int argc, char const *argv[]);
#ifdef __cplusplus
}
#endif
int test(int argc, char const *argv[]) {
fprintf(stderr, "%s\n", "test");
return 0;
}
Compilation line on MacOS
g++ -c test.cpp -o test.o && g++ test.o -o test -e _test
and on Linux
g++ -c test.cpp -o test.o && g++ test.o -o test -e test
I try on my MacOS with clang, g++ and Intel compiler, all 3 works fine.
And I try with g++ and the Intel compiler on Linux, always, the same error.
usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Any advice, explanation or solution, on what I am doing wrong or missing would be very helpful.
Thanks
Edit:
Currently, I have a "define" to create a main, but if we have lots of function we are obligated to do two compilations each time (one for the function version and one for the execution) and make finally the code heavier.
Like discussed in this topic is there a GCC compiler/linker option to change the name of main?
To don't do a XY I inherited from a bunch of small programs that I want to put to gather, that it is easier to use (for remote execution ...). However, each one need to be able to be executed independently if needed, for debugging,... I hesitate, between using "execv" and just convert each main as a function. I probably take the bad chose.
Edit:
The final goal is to be able to have independent programs. But that we can call from an external software too.
Solution:
The solution looks to be, to a call to the main through a dlopen
You cannot do that (and even if it appears to work on MacOSX it is implementation specific and undefined behavior).
Linux crt0 is doing more complex stuff that what you think.
The C standard (e.g. n1570 for C11) requires a main function for hosted implementations (ยง5.1.2.2.1) :
The function called at program startup is named main. The implementation declares no prototype for this function.
And the C++ standard also requires a main and strongly requires some processing (e.g. construction of static data) to be done before main is running and after it has returned (and various crt0 tricks are implementing that feature on Linux).
If you want to understand gory details (and they are not easy!), study the ABI and the (free software) source code of the implementation of the crt0.
I am trying to compile a function (not called main) that can be integrated in another code
BTW, to use dynamically some code (e.g. plug-ins) from another program, consider using the dynamic linker. I recommend using the POSIX compliant dlopen(3) with dlsym(3) on position-independent code shared libraries. It works on most Unix flavors (including MacOSX & Linux & Solaris & AIX). For C++ code beware of name mangling so read at least the C++ dlopen mini howto.
Read also the Program Library HowTo.
Problems with libraries, they cannot be executed, no ?
I don't understand what that means. You certainly can load a plugin then run code inside it from the main program dlopen-ing it.
(and on Linux, some libraries like libc.so are even specially built to also work as an executable; I don't recommend this practice for your own code)
You might take several days to read Drepper's How To Write Shared Libraries (but it is advanced stuff).
If you want to add some code at runtime, read also this answer and that one.
The final goal is to be able to have independent program. But that we can call from an external software too
You can't do that (and it would make no sense). However, you could have conventions for communicating with other running programs (i.e. processes), using inter-process communication such as pipe(7)-s and many others. Read Advanced Linux Programming first and before coding. Read also Operating Systems : Three Easy Pieces
The solution looks to be, to a call to the main through a dlopen
Calling the main function via dlopen & dlsym is forbidden by the C++ standard (which disallows using a pointer to main). The main function has a very specific status and role (and is compiled specially; the compiler knows about main).
(perhaps calling main obtained by dlsym would appear to work on some Linux systems, but it certainly is undefined behavior so you should not do that)

C++ Suspected stack overflow changing function parameters

I am working on implementing a user level thread library in C++ using setcontext(), makecontext(), getcontext(), and swapcontext() on a Linux system.
I am using a wrapper function to wrap the function the user wants to run as a thread. For example, the user calls newthread(funcPtr), and within the thread library funcPtr is passed to a wrapper function that runs it.
The error occurs differently depending on whether or not I initiate an unused string within the function. If I include the line string s = "a"; the program will run to completion, but gdb reveals that context is switching to somewhere within the string library. Without this line, the program segfaults after leaving the function wrapper.
The gdb output shows the corruption of the parameters to function().
I ran valgrind but did not see anything particularly out of the ordinary in the output, just many "Invalid read of size 4" and "Invalid write of size 4" warnings, usually within the C++ standard map.
You could try also AddressSanitizer for debugging. It can detect stack buffer overflows. Here's how to use it on Linux:
At least gcc 4.8 is needed for AddressSanitizer and libasan must be installed (e.g. on Fedora yum install libasan as root). Compile and link with -g -fsanitize=address and run the generated executable. AddressSanitizer stops and emits information if it detects the first error, no long log files have to be analyzed. Solve the reported problem, compile and run again until AddressSanitizer doesn't stop the program anymore. Unfortunately there might be false positives because you use swapcontext in your program, but it's worth a try. Instrumentation can be turned off for a specific function by adding the attribute no_sanitize_address: extern int func(void) __attribute__((no_sanitize_address));

IntelliSense error identifier "emlrtStack" is undefined

I am converting a MATLAB written function into C by "Matlab coder". After I get the converted files , the converted function always have first input argument as const emlrtStack *sp. Now when I am trying to test it on VC++ 2013, IntelliSense is giving mentioned above error.
I manually tried to locate this identifier in emlrt.h file but no such thing is present there. I tried to convert a simple multiply function with two input arguments[like, c=mul(a,b)] but still the converted function has this extra argument inside the function in addition to a and b.
(which means this argument is not function specific).
If someone has a solution to this or have experienced a problem like this, please share or help.
Moreover If someone know how to simply test these converted functions, it would be a much appreciated additional help .
It is likely that the code that was generated for a MEX function rather than a standalone target. MEX functions are binaries written C, C++ or Fortran that can be called like a normal MATLAB function. Generating code to produce a MEX function allows two things. First, you can test your generated code in MATLAB because you can call the MEX function from MATLAB like any other function. Look for a file named mul_mex.mex* after you do code generation and try to call it: mul_mex(1,2). The other use for generating a MEX function is that it can often be faster than the MATLAB code from which it was generated. MEX functions are only used in the context of MATLAB.
The parameter emlrtStack* that you saw appears in MEX generated code to aid in runtime error reporting. It is not present in standalone code that is designed to be run outside of MATLAB.
If you want to use the generated code in Visual Studio, or outside of MATLAB you should choose one of the standalone targets, LIB, DLL, or EXE. This page shows how to change the output type. To summarize, if using the command line you could say:
cfg = coder.config('lib'); %or 'dll' or 'exe'
codegen mul -config cfg -args {1,2}
If using the project interface, you click on the Build tab and choose static library or shared library in the "Output type" dropdown menu.
I would recommend reading this example that demonstrates how to use a generated DLL in Visual Studio.

C++ runtime errors in CodeBlocks when printing strings with cout <<

I recently started using CodeBlocks and began encountering odd runtime errors which I have traced back to printing strings using cout <<. For example, even the following..
#include <string>
#include <iostream>
int main()
{
std::string str;
str = "Hi!";
std::cout << str << std::endl;
return 0;
}
results in an error. It will compile fine (using Borland) but when I run it I get a pop up window saying 'test.exe has stopped working' and in the console I get the message:
Process returned -1073741819 (0xC0000005) execution time : 1.526 s
Press any key to continue.
It compiles and runs fine in MS Visual C++ and with G++ in Ubuntu.. any thoughts would be greatly appreciated!
Cheers,
Weatherwax
My one-off comment ended up helping solve the problem so here it is packaged up as an answer for future users:
This guy had a similar issue and it ended up being a linker issue which he
fixed. The fix is the last post in the thread, although reading the
whole thread could be useful for you.
Long Story short: Borland compiler is a bit dated and annoying to use. Ended up being a linker issue within borland. Better off using a different compiler like GCC/G++ or Visual Studio compiler.
This answer is here to elaborate on the root cause of the issue.
The reason for your crashing program is because the wrong runtime library is being linked. Specifically, your example is compiled as a single threaded object file(the default) but the linking step is using the multithreaded cw32mt.lib runtime -- the "mt" suffix at the end means multithreaded.
The solution is to make sure the runtime your program is compiled to use matches with the runtime you're linking against. A few ways to do this.
Important bcc32 compile switches:
-tW Windows GUI program. WinMain() is expected
-tWC Windows Console program. main() is expected. default.
-tWR Use dynamically linked runtime. Absence implies static runtime linkage.
-tWM Use multithreaded runtime. Absence implies single thread.
Compiling your example program as single threaded like this works:
bcc32 -oexample.obj -c example.cpp
ilink32 -ap example.obj c0x32, example.exe,, cw32.lib import32.lib,,
or you can compile it as multithreaded like this(note the -tWM switch matching up with cw32mt.lib):
bcc32 -tWM -oexample.obj -c example.cpp
ilink32 -ap example.obj c0x32, example.exe,, cw32mt.lib import32.lib,,
A third approach that is easier and less error prone is to not call the linker yourself. Instead, let the compiler drive the linker indirectly(similar to gcc):
bcc32 -tWM -oexample.obj -c example.cpp
bcc32 -tWM example.obj -eexample.exe
For your simple example, it can even be shortened to:
bcc32 -eexample.exe example.cpp
Lastly, you can pass the -tW switch multiple times. For example, this command compiles your example as a console program with multithread support and dynamic runtime linkage:
bcc32 -tWM -tWR -tWC -eexample.exe example.cpp
The produced example.exe executable is much smaller and its import table has an entry for CC3250MT.DLL confirming that the borland runtime is dynamically linked.
We should not assume that a non-functioning program is caused by nonconformity to the standard or a bug in the tool we're using without first investigating user error as a potential cause (even though in this case it's tempting to do so). In the OP's case, the code::block IDE didn't have the right commands setup for the toolchain being used.

Is it possible to symbolicate C++ code?

I have been running into trouble recently trying to symbolicate a crash log of an iOS app. For some reason the UUID of the dSYM was not indexed in Spotlight. After some manual search and a healthy dose of command line incantations, I managed to symbolicate partially the crash log.
At first I thought the dSYM might be incomplete or something like that, but then I realized that the method calls missing were the ones occurring in C++ code: this project is an Objective-C app that calls into C++ libraries (via Objective-C++) which call back to Objective-C code (again, via Objective-C++ code). The calls that I'm missing are, specifically, the ones that happen in C++ land.
So, my question is: is there some way that the symbolication process can resolve the function calls of C++ code? Which special options do I need to set, if any?
One useful program that comes with the apple sdk is atos (address to symbol). Basically, here's what you want to do:
atos -o myExecutable -arch armv7 0x(address here)
It should print out the name of the symbol at that address.
I'm not well versed in Objective-C, but I'd make sure that the C++ code is being compiled with symbols. Particularly, did you make sure to include -rdynamic and/or -g when compiling the C++ code?
try
dwarfdump --lookup=0xYOUR_ADRESS YOUR_DSYM_FILE
you will have to look up each adress manually ( or write a script to do this ) but if the symbols are ok ( your dSym file is bigger than say 20MB) this will do the job .