Hello All, I'm using Go1.8 mostly with plugins on Linux x86-64 (and I am only interested in Go since it has plugins, since I love the idea of having my monimelt <https://github.com/bstarynk/monimelt> program -GPL code on gitbub- emit at *runtime* some Go "source" code, in some temporary file, fork a compilation of that emitted source code into a plugin at runtime, and load that plugin and call code inside it, all that from the same process at runtime). See this question <https://groups.google.com/forum/#!topic/golang-nuts/IKh1BqrNoxI> and also https://blog.ksub.org/bytes/2017/02/12/exploring-shared-objects-in-go/
BTW, for C or C++ code doing all this is quite easy (see for example my manydl.c <https://github.com/bstarynk/misc-basile/blob/master/manydl.c> as simple example, or for a much more serious thing my GCC MELT <http://gcc-melt.org/>) once you understood that the main loading program should be linked with the -rdynamic flag and with the -ldl library (and will use dlopen(3) <http://man7.org/linux/man-pages/man3/dlopen.3.html> so its source code should #include <dlfcn.h>) : one just emit some C code in a temporary file like /tmp/emittedcode.c, run (e.g. with system(3) <http://man7.org/linux/man-pages/man3/system.3.html> ...) some careful compilation command into a plugin like gcc -shared -fPIC -O -Wall -g /tmp/emittedcode.c -o /tmp/emittedcode.so .... and load the plugin using void*plugin = dlopen("/tmp/emittedcode.so", RTLD_NOW | RTLD_GLOBAL); (I'm ignoring here error handling at dlopen stage). At last we should retrieve some symbol, e.g. some int returning function emittedfoo of two int arguments in that /tmp/emittedcode.{c,so} using code like typedef int sigfuntype (int,int); // signature of emitted function sigfuntype* emittedfunptr = (sigfuntype*) dlsym(plugin, "emittedfoo"); (again, ignoring handling of dlsym failure). Later the main loading program could use that function pointer e.g. like int y = emittedfunptr(2,3); and so on. Notice that with gcc passing -v -H helps a lot: it explains what files are read and what files are written by the gcc compiler. And sharing some code between a plugin and the loading program is easy (once -rdynamic is used to link the loading program): the plugin should just declare functions (in practice, #include some header from the program source directory) of the loading program and call them. I am able to code similar things in Ocaml, because I understand where the Ocaml compiler is putting information about plugins (in .cmxs files) and about modules (their interface is described by .cmi files). I am aware that I am using Go in some unusual way. Of course I want the plugin to have some packages, and to use some other packages provided by the main program. Of course I don't want binary code to be duplicated, so I need some binary shared code, that is the -linkshared and -buildmode=shared options are very important to me. I don't understand as much for the Go compiler, using the go tool. In particular I have a very *incomplete* understanding about : what is the exact structure and content of a Go compiled package file? Apparently it is some ar archive with __.PKGDEF & _go_.o members. Why? What are appropriate tools to inspect these package files? sometimes, it looks like the Go compiler is using HTTP requests to fetch source code (e.g. from github). When does that happen? What kind of HTTP requests? where is the output going for a given go command? What is the *exact* effect of -linkshared and of -buildmode=shared ? How does the compilation works?. I have the intuition (perhaps wrongly) that in many cases only the package and the import statements are parsed in .go files? When does that happens, and when is the file entirely parsed? What is the effect of import <https://golang.org/ref/spec#ImportPath> and what exactly does the import path means ? What exacty is the import comment <https://golang.org/s/go14customimport>?And custom imports? Their relation with -linkshared? I badly miss some equivalent for go of the -H option for gcc. In my dreams, I would like some -show option which would display the complete file path of successfully read files, and the complete URL of successful HTTP GET requests, and the complete file path of successfully written files. If that is easy to implement (and I believe it is), could someone explain me what files and functions of the compiler should I patch? I believe I am not alone in wanting this. I notice that many talks are proposing alternative builders (such as gb <https://getgb.io/>, which sadly is plugin incompatible today, or glide <https://glide.sh/>), or using Makefile with go, etc. I would be quite happy using some Makefile for Go with plugins, but sadly I am unable to write it (because of my misunderstanding of go tool and packages). I confess that I am blocked since several weeks because of such issues, and I am considering (sadly) giving up Go (and sadly going back to emit C or C++ code at runtime, like I did in the past). I would miss Go concurrent abilities and its multi-thread friendly garbage collector. My misunderstanding of Go internals -in particular with plugins and shared code in mind- is making me unhappy. I am willing, if so needed, to describe in every detail what I have tried in my monimelt <https://github.com/bstarynk/monimelt> project (on Github). If you are in France, in the Paris region, I can even go to your place with my laptop (But the people I have met at the recent Go meetup in Paris are not able to help because they don't care about plugins). Thanks for reading. Regards. -- Basile Starynkevitch <http://starynkevitch.net/Basile/> (France) bas...@starynkevitch.net -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.