Summary of situation:
built julia-1.2.0-rc2 from source for centos6 with gcc 6.4.0 and -DGLIBCXX_USE_CXX11_ABI=0
dlopen an .so which embeds some simple julia code. “Lifted” into global namespace with dlopen(RTLD_NOW | RTLD_GLOBAL)
from a maya plugin.
jl_init() results in this assert:
void* jl_init_llvm(): Assertion `jl_TargetMachine && “Failed to select target machine -” " Is the LLVM backend for this CPU enabled?"’ failed.
Any ideas? A toy julia embedding works fine ( not loaded from maya )
versioninfo():
Julia Version 1.2.0-rc2.0
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, broadwell)
Please don't double post without waiting for a reply and without any cross referencing.
https://discourse.julialang.org/t/assertion-jl-targetmachine/26483
This is likely due to linking issues especially when you are loading into a process that's using llvm.
readelf -d path to maya/lib/*.so | grep LLVM
readelf -d path to maya/lib | grep LLVM
no hits.
Here's few relevant variables printed from gdb just before the offending call.
TheTriple = {Data = {static npos = 18446744073709551615, _M_dataplus = {
= llvm::Triple::UnknownVendor, OS = llvm::Triple::Linux, Environment = llvm::Triple::GNU, ObjectFormat = llvm::Triple::ELF}
TheCPU = (std::basic_string
ataplus = {
"}}
targetFeatures = {
203f43e8}, FirstEl = {
No data fields>}, Storage = {InlineElts = {{
"/dev/pts"},
000\000\000;212\000"},
Here are the same variables from a toy executable dlopening the same libjulia, which works. jl_TargetMachine is non-null.
TheTriple = {Data = {static npos =
TheCPU = (std::basic_string
targetFeatures = {
{
id>> = {
000\000\000\000"},
000"},
buffer = "\000\003\034\177\025\004\000\001"},
r = "\000\021\023\032\000\022\017\027"},
\026\000\000\000\000\000\000"},
These variables are not useful. It's pretty clear that it's the code that you called that's causing the problem and you still need to figure out which version of LLVM it is calling, or if there's any possibly of symbol mixing.
What do you mean by the code that I called? I called jl_init() in both cases. In both cases jl_init() was from the same libjulia.so. Perhaps you mean the code that called me?
I've ruled out llvm being used by maya to a "depth" of 1 ( direct library dependencies ) and somewhat to the next level. I can wade through the spew of LD_DEBUG although this is getting out of my depth.
Hey. Maybe you can help? \s
Could you guide me on how to figure out which version of LLVM it's calling and how to rule out the possibility of symbol mixing?
By "code you called" I mean "which version of LLVM it is calling". No I do not mean the code that calls you.
Hey. Maybe you can help? \s
I've said everything I could based on the information you provide but most of what you said are in some "summary" that doesn't include enough detail for me to judge whether I can trust what you says.
Examples,
built julia-1.2.0-rc2 from source for centos6 with gcc 6.4.0 and -DGLIBCXX_USE_CXX11_ABI=0
What build parameters? In particular what LLVM?
readelf -d path to maya/lib/*.so | grep LLVM
readelf -d path to maya/lib | grep LLVM
Not exactly sure what you are trying to say here since LLVM doesn't have to appear anywhere here (assuming this is where maya keeps it's library). Your graphic drivers could use LLVM and code could statically link LLVM.
I've ruled out llvm being used by maya to a "depth" of 1 ( direct library dependencies ) and somewhat to the next level.
I'm not sure how you come to this conclusion. If it's from the readelf result then I don't think that's true.
Could you guide me on how to figure out which version of LLVM it's calling and how to rule out the possibility of symbol mixing?
OK, this one I assume you at least know how to get started..........
I guess it might not be obvious and indeed I don't think I learnt this from anywhere in particular so that's fair..........
What I meant is just to step into a LLVM call to figure out where the code is. Just look at $pc after stepping into a LLVM call and see where it lands.
You should also be able to figure out what symbols are loaded but I don't remember/know how to do it.
I ran with
env LD_DEBUG=libs maya
loaded my plugin
after grepping output for llvm
I find four libraries.
10047: 126838: find library=libLLVM-6.0.so [0]; searching
10049: 126838: trying file=path/julia/1.2.0-rc2/lib/julia/tls/x86_64/libLLVM-6.0.so
10050: 126838: trying file=path/julia/1.2.0-rc2/lib/julia/tls/libLLVM-6.0.so
10051: 126838: trying file=path/julia/1.2.0-rc2/lib/julia/x86_64/libLLVM-6.0.so
10052: 126838: trying file=path/julia/1.2.0-rc2/lib/julia/libLLVM-6.0.so
10062: 126838: calling init: path/julia/1.2.0-rc2/lib/julia/libLLVM-6.0.so
Now I have seen this, which I don't call because the executable is maya ( called me ), and my code is a shared library ( maya plugin ). Is this a clue to what is going wrong?
from: https://docs.julialang.org/en/v1/manual/embedding/index.html
JULIA_DEFINE_FAST_TLS() // only define this once, in an executable (not in a shared library) if you want fast code.
I'll check the program counter and see what I see.
Sorry, that's only one library, the others are where it's searching and not finding.
after a tedious gdb session checking $pc and info symbol I'm pretty sure there is only one library, one version of LLVM being used. The one included in julia/1.2.0-rc2 that I build from source. libjulia-debug.so -> julia/libLLVM-6.0.so
That's it. No symbol mixing. A single LLVM version.
It ends up failing here:
0x00007fd4a9b082a0 in std::string::assign(char const*, unsigned long)@plt () from path/julia/libLLVM-6.0.so
(gdb)
std::string::assign (this=0x7fff4d769c80, __s=0x7fd4ab16c1a8 "Unable to find target for this triple (no targets are registered)", __n=65)
The triple is included earlier in this thread. Maybe someone who knows about triples and targets can look at this?
Not sure where to go from here. I suppose I can build libLLVM in debug and step in there. Any suggestions?
So, could you compare the triple you get with your toy program to the triple which is used when loaded in maya? Personally I'd be modifying codegen.cpp to start dumping out info like the triple in a readable format rather than (or in addition to) using the debugger.
I think building LLVM in debug mode would be a good step: working a bit on getting your tools / environment right can save hours of confusion in a debugger.
The triple should be the same and it's conformed above. In general the input to that function isn't really generated through llvm and that's why I said the dump isn't useful. You can certainly pri~t them to confirm.
That's also why I said it's likely from the llvm side and probably a linking issue since the interaction with llvm is fairly limited up to this point.
The triples are actually the same:
TheTriple = Data="x86_64--linux-gnu", Arch=llvm::Triple::x86_64, SubArch = llvm::Triple::NoSubArch, Vendor = llvm::Triple::UnknownVendor, OS = llvm::Triple::Linux,Environment = llvm::Triple::GNU, ObjectFormat = llvm::Triple::ELF
So is TheCPU.
targetFeatures look different though. Which are not printed out nicely, so I could do that.
Not sure if there is any internal state in LLVM during the call to the function to map "the triple" or not.
That's also why I said it's likely from the llvm side and probably a linking issue since the interaction with llvm is fairly limited up to this point.
We run a pretty limited and system, I'm not aware of any other instances of LLVM. Assuming there is only one version of llvm, what other linking errors could arise? In both cases it uses the same llvm and lib though, so it would be some kind of dynamic linking problem.
targetFeatures look different though
Interesting, maybe.
In general the input to that function isn't really generated through llvm and that's why I said the dump isn't useful. You can certainly print them to confirm.
Sure, fair enough (in case it's not obvious to @Orbots, I'd like to point out that @yuyichao knows far more about codegen than myself).
My approach to this kind of thing is kind of simple minded: log the heck out of everything and doggedly verify the assumptions you're making. If you don't know about it already, you may find jl_safe_printf useful for internal contexts where normal IO would be a problem.
Which are not printed out nicely, so I could do that.
Sure. That being different in any significant way is pretty strange, since the logic only depends on CPU features. Now if the host program somehow changes the way cpuid works or changes how one can read data from the system image that's possible but otherwise it shouldn't make a difference.
You can dump an internal version of it by calling jl_dump_host_cpu() in gdb.
I'm not aware of any other instances of LLVM. Assuming there is only one version of llvm, what other linking errors could arise?
I'll be pretty surprised if there's not a single other llvm on the system, especially since maya sounds like a program that'll want it. Maybe maya is more cpu based than I though or maybe you don't have any fancy graphic.... I don't know.
I'll be pretty surprised if there's not a single other llvm on the system, especially since maya sounds like a program that'll want it. Maybe maya is more cpu based than I though or maybe you don't have any fancy graphic.... I don't know.
This sounds like this could possibly be a render farm deployment of Maya (?) Last I knew a bit about this kind of thing (several years ago now), production rendering was still heavily CPU based for a lot of things. GPU was making inroads but it's not straightforward to do for things like monte carlo ray tracing with complex materials... and other similar techniques.
You're definitely right that Maya is the kind of program that could come with other LLVM dependent plugins. For example, OSL (open shading language) compiles down to LLVM. @Orbots perhaps you could describe your system setup a bit?
This sounds like this could possibly be a render farm deployment of Maya
OK. I just searched "maya plugin" and found it's from autodesk so I assume it's graphic related. If it's CPU based then maybe LLVM from GPU driver is not an issue.
Now since the simplest way of verifying if the correct LLVM is called doesn't show a problem (i.e. the address of llvm::EngineBuilder::selectTarget(...) is correct) then the next thing is to verify that the input is correct....
LLVM is still the most likely interaction between maya and julia that I could think of but it could certainly be more subtle....
The system setup... yeah it's definitely complex. Not a render farm deployment. AFAIK the "role" I'm launching maya in doesn't have (any?) GPU related code associated with it, some roles do have this, but it's opt-in and usually cuda. There is a newer viewport api for maya, but again, I don't think any of the plugins in my role use it. I didn't see any llvm symbols from LD_DEBUG other than the julia ones though,.
How would I see if there was a mixup between a GPU driver's version of llvm and Julias?
How would I see if there was a mixup between a GPU driver's version of llvm and Julias?
I assume the output from LD_DEBUG can tell you something about it but I'm not sure since, fortunately, I have never had the need to........ Tracing the call through in gdb had been enough for me so far....
The easiest thing to check right now is still to check the features array. Both by dumping target.second and by calling jl_dump_host_cpu(). (Either in gdb or just doing that in codegen.cpp.)
output of jl_dump_host_cpu() for both plugin and toy are the same. However the contents of the llvm::AlignedCharArray<8ul, 8ul>> in targetFeatures ( pasted above ) between the two are different. Somehow it seems copying the data into those strings is going wrong.
Is it true that the value of the targetFeatures data structure should be the same given the same jl_dump_host_cpu() results?
The content shown above doesn't matter. Those are unused memory for static elements containing garbage.
Ok, thanks. You just saved me a fruitless gdb session!
But target.second should be valid and the same for both, right?
I'm trying to build llvm in debug mode. I set LLVM_DEBUG := 1 in Make.inc, but I still can't step into selectTarget source. How do I get julia to rebuild llvm and download the source? All I see are headers and the build is much to quick to be a full llvm build.
But target.second should be valid and the same for both, right?
Yes. That you should be able to confirm.
Ok. You were right from the beginning. There is some LLVM mixing from a graphics lib. Happens earlier in the jl_init_llvm procedure call.
I noticed the llvm variablestatic Target * FirstTarget was always NULL in the plugin version. I did some fine grained stepping which lead to this in the call to InitializeNativeTarget()
0x00007fcfb97aee60 in LLVMInitializeX86Target () from path/vray_for_maya/3.6.27936_for_maya2018/lib/libvrayoslexec.so
This lib as llvm symbols and code internally and not dynamically linked.
So the Targets were being set in that library and not the julia linked one.
Cool. So then. How do I fix this?
Cool :-p
I have not done much with all sort of linking tricks you could do with llvm so someone else should be able to help you better on that.... I thought the symbol versioning is supposed to solve this issue when you don’t need the two copies to interact with each other although there could be bug or corner cases that’s not covered or even sty to do with the old toolchain version on your setup......
Dumping the relevant symbols from your Julia’s llvm, the maya llvm and the official binary llvm and see if the symbol renaming works correctly could be a good start if no one comes up with anything better.
The vray plugin looks to namespace all it's llvm code ( for example _ZTVN13VRay_llvm_v3317X86TargetLoweringE) except for these three:
LLVMInitializeX86Target
LLVMInitializeX86TargetMC
Which are also present in libjuila.so ( reference ) and libLLVM-6.0.so ( ) for the same symbol.
libLLVM-6.0.so symbols look like this otherwise _ZTVN4llvm17X86TargetLoweringE
Could julia explicitly get those offending procedures via dlsym from julia/libLLVM-6.0.so and call them?
Should I raise a ticket with LLVM or ChaosGroup ( vray guys )?
As a super hack I could actually do that from my plugin, so it would populate the Target list. I really wouldn't want to do that.
Here are some symbol table dumps to look at:
readelf -s path/julia/1.2.0_rc2/lib/libjulia-debug.so | grep -i LLVMInitializeX86Target
251: 0000000000000000 0 FUNC GLOBAL DEFAULT UND LLVMInitializeX86Target@JL_LLVM_6.0 (4)
1489: 0000000000000000 0 FUNC GLOBAL DEFAULT UND LLVMInitializeX86TargetMC@JL_LLVM_6.0 (4)
2325: 0000000000000000 0 FUNC GLOBAL DEFAULT UND LLVMInitializeX86TargetIn@JL_LLVM_6.0 (4)
21386: 0000000000000000 0 FUNC GLOBAL DEFAULT UND LLVMInitializeX86Target@@
22624: 0000000000000000 0 FUNC GLOBAL DEFAULT UND LLVMInitializeX86TargetMC
23459: 0000000000000000 0 FUNC GLOBAL DEFAULT UND LLVMInitializeX86TargetIn
readelf -s path/julia/1.2.0_rc2/lib/julia/libLLVM-6.0.so | grep -i LLVMInitializeX86Target
4542: 0000000001a067c0 115 FUNC GLOBAL DEFAULT 12 LLVMInitializeX86Target@@JL_LLVM_6.0
7033: 0000000001a5ae20 229 FUNC GLOBAL DEFAULT 12 LLVMInitializeX86TargetMC@@JL_LLVM_6.0
13381: 0000000001a66750 102 FUNC GLOBAL DEFAULT 12 LLVMInitializeX86TargetIn@@JL_LLVM_6.0
39493: 0000000001a067c0 115 FUNC GLOBAL DEFAULT 12 LLVMInitializeX86Target
41984: 0000000001a5ae20 229 FUNC GLOBAL DEFAULT 12 LLVMInitializeX86TargetMC
48332: 0000000001a66750 102 FUNC GLOBAL DEFAULT 12 LLVMInitializeX86TargetIn
md5-f517d153b87d6f7d321d308cc0a4dbf9
readelf -s lib/linux_x64/gcc-4.4/libvrayoslexec.so | grep -i LLVMInitializeX86Target
4800: 0000000000636d00 86 FUNC GLOBAL DEFAULT 11 LLVMInitializeX86TargetIn
7895: 000000000070a0c0 851 FUNC GLOBAL DEFAULT 11 LLVMInitializeX86TargetMC
10527: 0000000000636e60 61 FUNC GLOBAL DEFAULT 11 LLVMInitializeX86Target
11898: 0000000000636d00 86 FUNC GLOBAL DEFAULT 11 LLVMInitializeX86TargetIn
12813: 0000000000636e60 61 FUNC GLOBAL DEFAULT 11 LLVMInitializeX86Target
14322: 000000000070a0c0 851 FUNC GLOBAL DEFAULT 11 LLVMInitializeX86TargetMC
Could julia explicitly get those offending procedures via dlsym from julia/libLLVM-6.0.so and call them?
No. That introduces more problems (how do you find the llvm for example? Duplicate the linker logic? It's worse if you can't reliably find the right one which is a much more likely problem than embedding in a environment that has llvm loaded...)
Here are some symbol table dumps to look at:
I'm not sure how the readelf -s works but the last 3 symbols in all outputs looks like truncated symbols (confirmed locally) and I don't believe those actually exists in the binary. It does seems that the symbol versioning is working correctly so I'm not sure why the wrong (unversioned one) is picked up. Dynamic linking log might provide some hint...
Also, right now this is very unlikely to be a julia issue.
Here's where I'm at now.
I've managed to create a MWE that doesn't involve maya.
Here's a graph of the dependencies. All explicitly via dlopen except for julia/libLLVM.so.
This mimics the plugin pattern maya uses ( and many other programs ).
DummyExe -> libembedJulia.so -> libjulia.so -> jula/libLLVM.so
DummyExe ->libvray.so ( with LLVM in it ) to replicate the problem I see in maya.
According to: https://akkadia.org/drepper/dsohowto.pdf
"All methods which depend on symbol versioning have one requirement in common: it is absolutely necessary for the users of the DSO to always link with it"
I don't know what the "users of the DSO" is in this context. But taking a hint I added -Lpath_to_julia/lib/julia -lLLVM to DummyExe. And it worked.
Adding that explicit -lLLVM link to libembedJulia.so did not work. Which is confusing, you'd think libembedJulia.so would be a user of libjulia-debug and julia/libLLVM.
In this case DummyExe is maya! I can't very well recompile off the shelf commercial software. So that's a non-starter.
If I link DummyExe with julia/libLLVM.so then it will resolve the correct symbol when I dlopen(libembedJulia.so) and call jl_init (in libjulia ) which then calls LLVMInitX86Target in libLLVM.so. LLVMInitX86Target is also in libvray.so.
Also what works is if I dlopen(libvray.so, RTLD_LOCAL) rather than RTLD_GLOBAL from DummyExe.
I'm nearly certain maya dlopen's any plugin with RTLD_LOCAL by default, because after I finish with this issue I have to confront that hoop next. Which is easy enough, I can get libembedJullia.so to dlopen(libembedJulia.so, RTLD_GLOBAL) to "lift" it into the global space.
I'm guessing the vray developers did a similar thing and are lifting their plugin into the GLOBAL space. Creating a conflict with my plugin. I think they also have some other flags they passed to ld that has the net effect of preferring their symbols to any other libs. I'm guessing this because it doesn't matter what order I open libvray.so or libembedJulia.so, the LLVMInitializeX86 from libvray is always choosen to resolve that symbol.
Any ideas? I totally miss something or is what I just wrote complete non-sense?
I thought I might try statically linking LLVM in the julia build... but that doesn't seem to be an easy thing to do. Appears I'd have to build my own static libs+patches for LLVM-6.0.1 and get julia to link with that.
Heres a MWE:
app.cpp
// emulate what a commercial applications plugin system would be like in Linux
#include <dlfcn.h>
int main(void)
{
void *handle;
char *error;
// open this with RTLD_GLOBAL and it will cause the jl_init() call to segfault or LLVM to find no targets
dlopen("shadow.so", RTLD_LAZY | RTLD_GLOBAL);
//dlopen("shadow.so", RTLD_LAZY | RTLD_LOCAL);
handle = dlopen("libplugin.so", RTLD_LAZY );
typedef int (*function_call_t)();
function_call_t testFunction = (function_call_t) dlsym(handle, "testFunction");
int r = testFunction();
dlclose(handle);
return 0;
}
plugin.cpp
// a plugin that is loaded by app at runtime. typical plugin architecture pattern
#include <julia.h>
#include <stdio.h>
#include <dlfcn.h>
extern "C" void liftNamespace()
{
void *handle;
handle = dlopen("libplugin.so", RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
}
extern "C" int testFunction()
{
static bool lifted = false;
if( !lifted ){
liftNamespace();
lifted = true;
}
jl_init();
jl_eval_string("println(rand()*sqrt(2))");
jl_atexit_hook(0);
return 42;
}
shadow.cpp
// some other plugin that has LLVM linked statically and has this function in .dynsym
#include <stdio.h>
extern "C"{
namespace llvm{
static bool ok = true;
void LLVMInitializeX86Target(){
printf("what are you doing here?\n");
ok = !ok;
}
bool LLVMInitializeNativeTarget(){
LLVMInitializeX86Target();
return ok;
}
}
}
Makefile
using gcc 6.4.0 with binutils 2.29.1. we need to specify gcc/binutils explicitly because we are on CentOS 6.
CXX = g++
shadow: shadow.cpp
$(CXX) -g -shared -o shadow.so shadow.cpp -fPIC -rdynamic -B$(BINUTILS_ROOT)/bin
plugin: plugin.cpp
$(CXX) -g -c plugin.cpp -std=c++11 -DJULIA_ENABLE_THREADING=1 -D_GLIBCXX_USE_CXX11_ABI=0 -fPIC -isystem$(JULIA_IPATH) -B$(BINUTILS_ROOT)/bin
libplugin: plugin
$(CXX) -g -shared -o libplugin.so plugin.o -std=c++11 -DJULIA_ENABLE_THREADING=1 -D_GLIBCXX_USE_CXX11_ABI=0 -B$(BINUTILS_ROOT)/bin -fPIC -L$(JULIA_LIB_PATH) -L$(JULIA_LIB_PATH)/julia -Wl,--export-dynamic -Wl,-rpath,$(JULIA_LIB_PATH) -Wl,-rpath,$(JULIA_LIB_PATH)/julia -ljulia-debug #-lLLVM
app: app.cpp libplugin
$(CXX) -g -o app app.cpp -fPIC -rdynamic -std=c++11 -B$(BINUTILS_ROOT)/bin -D_GLIBCXX_USE_CXX11_ABI=0 -Wl,-rpath,'.' -ldl
.PHONY: all
all: shadow plugin libplugin app
Can't touch app or shadow. Anything that can be done either in plugin, julia build or, as a last resort, julia code to fix this?
The basic problem seems to be that if an unversioned symbol foo() was loaded into the symbol table as GLOBAL first it preempts any subsequent symbol resolution/load for foo() versioned or unversioned, LOCAL or GLOBAL. If the both libraries are versioned, everything works fine. But you can't count on the other DSO being versioned. So this seems to be a case that isn't fixed by symbol versioning in Julia.
Few things I tried:
Seems it's JuliaCon time so I've been sort of talking to myself here :) No big rush, I'm not blocked anymore, just not 100% satisfied with my fixes and worried it might pop up again.
@yuyichao Did you have chance to read my replies? I'd like to be able to promote julia within my company and then my industry. I can't really do so without having a working solution for production.
Currently I have a very duct-tape and chewing gum solution where I have 2 versions of julia installed. One statically linked to LLVM so I can build a plugin and then another that dynamically links with LLVM. The statically linked one can't use BinaryProvider.jl so I have to run the dynamically linked one to add some key packages. Also apparently several packages will not work with the statically linked one ( GPU based stuff, which we would like ).
@vchuravy do you have an idea on what can be done here?
I can ask ChaosGroup to add symbol versioning to their vray plugin, but that doesn't protect us from the next llvm plugin without symbol versioning.
@yuyichao Hello? Could I get a status update here?
I don't understand how julia as an organization works. Seems like this repo is the open-source part of Julia? Obviously there are some folks employed doing Julia development who are interested in Julia being use in "production" environments, could you refer me to one of them?
Err, what kind of update do you want? I've told you everything I know about this including that I don't know any other linking tricks so AFAICT I'm done with this issue with my last reply.
The symbol versioning is supposed to fix this and I don't know why it doesn't. If you can find a way to convince the linker to do what you want, or if you think this is a bug in the linker and report a bug, or if you can find any other way to fix this without affecting any other usage (so using dlopen is not one of them) then you are welcome to propose that. Otherwise this is as much as an issue in your environment/dynamic loader as it is in julia so I don't know anything else that can be done here.
Also, I'm not employed by anyone related so you are asking the wrong person...... i believe the julia-computing website might have some contact info for conmercial support.
That's an update. Thank you.
From what I understand, and no one has contradicted this, symbol versioning only works reliably if all libraries are versioned. An unversioned symbol loaded before a versioned symbol ( in same namespace ) will take precedence. I use namespace in the RTLD_* sense here.
I think I've shown that this is not just "my" environment, but any Linux plugin-based architecture.
Fixes are then either do something about namespaces ( dlopen, static linking llvm ), optionally renaming julia's llvm symbols, or policing all non-symbol versioned libs.
The policing option is reactive and not really sustainable because a new .so introduced into a working environment could break all julia plugins. Loading plugins in a specific order where possible is an option. I could do this, but I don't want to, because it's a pain to support and would cost my organization $ due to down time when stuff breaks.
The others two solutions do involve julia. #12644 seems it could do the trick if it was adopted.
I don't understand how julia as an organization works. Seems like this repo is the open-source part of Julia?
The following might help: https://julialang.org/blog/2019/02/julia-entities
Unfortunately there's only a few people with the right expertise to solve this and their time is limited, hence the uncomfortable silence on this issue.
Thanks, that blog post clears things up.
I'll keep this issue open for now.
Definitely keep this open — the MWE seems great and the desired use case is completely reasonable.
Most helpful comment
Heres a MWE:
app.cpp
plugin.cpp
shadow.cpp
Makefile
using gcc 6.4.0 with binutils 2.29.1. we need to specify gcc/binutils explicitly because we are on CentOS 6.
Can't touch app or shadow. Anything that can be done either in plugin, julia build or, as a last resort, julia code to fix this?