I've been looking into online resources on writing GCC plugins. I'm currently using GCC version 7.3.0. I attempted writing a simple plugin that contained a callback which would be called upon PLUGIN_FINISH_TYPE. It worked fine.
Next, I'm trying to write a plugin that uses a "gimple pass" similar to the example listed here. However, struct gimple_opt_pass does not seem to exist.
I tried looking for header files that declare this struct. I found that tree-pass.h has the following code block :-
/* Description of GIMPLE pass. */
class gimple_opt_pass : public opt_pass
{
protected:
gimple_opt_pass (const pass_data& data, gcc::context *ctxt)
: opt_pass (data, ctxt)
{
}
};
How can I see this from within my plugin? I don't seem to be able to use this in the way as described in the link above.
With the current GCC plugin API, is it possible to write a pure C plugin(as opposed to having to use C++).
I've found the answer. The API for GCC plugins changed dramatically from 4.8 to 4.9. Uptil 4.8, gimple_opt_class was a structure that you could create an instance of and use with register_pass_info. From 4.9 onward, it is a class that you would need to inherit from, create an instance of and use with register_pass_info.
In order to be able to use pure C plugins with GCC, it would seem like using the API for version below and including 4.8 would be the solution. 4.6 seems to be working fine for me, but does to seem to have debug/dump functionality in it.
Related
I just recently started working with c++ templates in order to use a template I know you do template<typename T> class MyClass, but how do I apply a filter? In C# you can do public class MyClass<T> where T:filterClass and in Java it's public class MyClass<T extends/implements filterClass>. I've tried following the tutorial at https://msdn.microsoft.com/en-us/library/a174071k.aspx but my compiler doesn't recognize the flag -clr or the keywords generic and where. I've looked on cppreference.com and cplusplus.com and couldn't find anything. Using the --version option on my compiler returns g++ (Ubuntu 5.4.0-6ubuntu~16.04.1) 5.4.0 20160609. I am also using c++11 and would prefer not to use external libraries.
I'm working on software for an embedded system that uses GStreamer 0.10.36. My goal is to keep the software as small as possible in terms of Flash memory space, so I'd like to statically linking the GStreamer plugins I need. According to the Core Reference Manual:
"There are options to statically link plugins to an app or even use
GStreamer without a plugin repository in which case gst_plugin_load()
can be needed to bring the plugin into memory. "
Unfortunately, it's not clear to me exactly what I need to do to bring the plugin into memory such that a subsequent call to gst_element_factory_make() completes successfully.
I'm doing the following:
Building GStreamer with --enable-static and --disable-registry set.
Linking the static library into my application
Call gst_element_factory_make() to create an element
Right now I'm only doing this for one plugin (tcpclientsink) out of several as an experiment. I had to edit the Makefile for that plugin to remove a --disable-static statement to get the libgsttcp.a file to build. I assume the library is good, but I'm not sure if there is a good way to verify that. gst-inspect does not appear to work on static libraries.
Note: If I call load_gst_plugin(/path/to/libgsttcp.a), GStreamer fails to load the plugin because of an invalid ELF header.
How does one load a statically linked GStreamer library?
I made an app in which all plugins are compiled inside the app (so it is self-containing)... Maybe this is another option for you, or do you really need to link to the library?
I got my usual code (plugin.c and plugin.h) that I used to compile the plugins in a shared library. I add an extra wrapper header that containts static registration code
static gboolean myplugin_init(GstPlugin * plugin)
{
gboolean ret;
gst_controller_init(NULL, NULL);
GST_DEBUG_CATEGORY_STATIC (gst_myplugin_debug);
GST_DEBUG_CATEGORY_INIT(gst_myplugin_debug, "myplugin", 0, "description");
ret = gst_element_register(plugin, "myplugin", GST_RANK_NONE, GST_TYPE_MECIMOTION);
return ret;
}
void gstmyplugins_register_static()
{
gst_plugin_register_static(
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"myplugin",
"description",
myplugin_init,
"0.0.1",
"LGPL",
"myplugins",
"GStreamer",
"http://gstreamer.net/");
gst_plugin_register_static(
...
}
then inside the code for my app i call this registration:
gstmyplugins_register_static();
then continue with
gst_element_factory_make("myplugin", NULL);
hope this helps.
With some help from the GStreamer developers I found the answer.... don't use version 0.10.36. :)
Basically the ability to build static plugin libraries was added/fixed in later versions. To get it to work in 0.10.36, I've had to back port changes from the GStreamer SDK and GStreamer 1.x into 0.10.36. Things are still a work in progress, but I am able to build libgstcoreelements.a and statically link with it. If I wasn't already building a modified version of 0.10.36, I probably would have just used the SDK.
Update
I created static versions of all of the libraries I'm using. My GStreamer library is now a bit of a hybrid between 0.10.36, the SDK, and 1.2.2, but it works. I wouldn't recommend this solution for anyone though. Use the SDK or version 1.x.
I think I found a bug in the libc++ list implementation. The following code will produce a compiler error (Field has incomlete type 'foo') when using certain build settings in xcode:
#include <list>
using namespace std;
class foo {
public:
list<foo> bar;
};
The settings are the following:
XCode Version: 4.4.1
C++ Language Dialect: C++11 or GNU++11
C++ Standard library: LLVM C++ standard library with C++ extensions (libc++11)
Using GCCs libstdc++ will resolve the error.
Not using the C++11 dialect will resolve the error.
Using vector instead of list will resolve the error.
I think it is a bug in the list implementation, but I am not sure.
Forgive my ignorance, but I don't know what I should do to resolve this issue.
Switching to vector is not an option in my project and I definitely need C++11 features. That also includes shared_ptr, but the headers are missing when using GCC. Beside that, apple does not seem to provide new versions of GCC anymore.
I would very appreciate it if somebody could recreate this issue, maybe with newer header from libc++.
Also, if updating LLVM/libc++ would resolve this issue, do you recommend it?
C++ Standard 17.6.4.8:
In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++ standard library depends on components supplied by a C++ program. If these components do not meet their requirements, the Standard places no requirements on the implementation.
In particular, the effects are undefined in the following cases:
...
if an incomplete type (3.9) is used as a template argument when instantiating a template component,
unless specifically allowed for that component.
None of the standard library's container class templates, including list, mention any such allowance for an incomplete type. So your program is an invalid one that might happen to work with some compilers. That can't be considered a bug in the standard library implementation.
I have a project compiled using __cdecl calling convention (msvc2010) and I compiled boost using the same compiler using the default settings.
The project linked with boost but I at runtime I got an assert message like this:
File: ...\boost\boost\program_options\detail\parsers.hpp
Line: 79
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
There are the following questions:
what calling convention does boost build with by default on Windows (msvc2010)
how to I compile boost with __cdecl calling convention
why boost wasn't able to prevent linking with code with different calling conventions? I understood that boost has really smart library auto-inclusion code.
Update #1
It looks that boost does compile and link with proper calling convention, still at runtime I get the above problem. I did a sample application using the same code and it works but in my application it fails. The only difference could be from project configuration or includes/stdafx.h
Just use
bjam ... **cxxflags=/Zp4**
while building boost libraries.
As far as I know there's not way to make C++ use cdecl calling conventions (see MSDN Calling Convention). The C++ method calling is just different from C. The only opportunity that you have to use one of the C calling conventions is for functions, which include class static functions in C++. If you know that's the case you can try forcing the option when building by adding the option during the build:
bjam cxxflags=/Gd ...
(see BBv2 Builtin features)
Or to make it "permanent" set up a user-config.jam with your compiler and add it to the build options for all BBv2 msvc builds (see BBv2 Configuration and related docs). As for you other questions:
Boost uses the default calling convention MSVC uses, except for cases where it overrides it at the code level. I don't know where those are as they are library specific. So you'd have to search the code for the "__*" code decorators.
See above for partial answer.
Detection; there are two reasons: There is a limit to how many different options we can reasonably detect for for building as it's an exponential growth of different possible variations so we limit it to the most important cases. And in the case of calling convention, it's not actually possible since it's something that can be changed on a per function basis.
I found the cause of the problem inside one of the shared property files: <StructMemberAlignment>4Bytes</StructMemberAlignment>
If I remove it the code will work. Still, I'm not sure why this is happening and how could I solve it without removing the above code (that was required by another library).
I added another question regarding boost and structure member alignment.
I'm creating a package that is going to be used by R (the statistical program), I'm not an expert using this application but I have managed to create a very simple package, using the following logic, I have some classes in C++, as the code has to be compiled using the R compiler and it only allows C code, I have a wrapper C code that call the C++ methods, and later I have an R script that call the methods exposed by the C code, so basically is a communication like R <-> C<->C++.
The full tutorial that I used to create this package is found here, I add it as a reference.
Now my problem is that I need to add some functionality to the package that I already created, what I need to do is to add code for late binding to a COM object which is another product that I created and that is registered using regasm tool.
This is the c++ code that I'm using to try to late bind to the COM object, I'm trying to use IDispatch to do so:
{
...
CLSID clsid;
HRESULT hr = CLSIDFromProgID((WCHAR*)"My Com object ProgId", &clsid);
if(FAILED(hr))
return;
...
}
I didn't paste the whole code because only with these lines the compiler is giving me troubles already, the command I use to compile is
R CMD SHLIB Cclass.cc C++class.cc
Where "Cclass.cc" has the C code that call the c++ methods and "C++class.cc" is actually the C++ code.
When I compile these classes the compiler says "undefined reference to `CLSIDFromProgID#8'collect2: ld returned 1 exit status"
I"m sure I have added all the header files that I need, that's why I believe my problem is that I'm not including ole32.lib and oleaut32.lib which are static libraries.
So, my question is, how can I include this libraries in order to be able to use the methods for late binding, like CLSIDFromProgID(...) or QueryInterface(...). Also if anyone believes that my problem is not linking this libraries, but something else, it would be great if can point me to which my problem may be.
Also have in mind that I need to link with those statics libraries in a way that they can be compiled without problem by the R compiler, which if I'm not wrong is a merely c compiler.
I've not tried doing this with C/C++ but rather with Fortran. I had a similar problem in that some standard IO libraries weren't being included in the library I was created. In the end I just included them all and compiled using the Fortran compiler. I didn't use any of the R compiler utilities, just compiled as if I were compiling a static Fortran library normally for use with anything else. This worked fine.
A debug path might be to compile as a static library using gcc (or whatever you're using) then try to include and call that static library from another C program, then if that works try with R.
Hope this is helpful, writing these R packages is pretty hard unless you're using vanilla C or Fortran as far as I can tell.