I have a FORTRAN 95 program that needs to make some calls to the LAPACK library. I recently found out that Cygwin because it can install LAPACK as an extra option.
Well, LAPACK exists in the /lib/lapack/ directory as "cyglapack.dll". Having only a very informal training in Fortran programming, I have no idea how to reference a .dll library as opposed to a .mod module.
Any suggestions or directions to articles answering my question are GREATLY appreciated!
(P.S. I did search first.. I don't think I know the proper terms to get a useful article.)
Conceptually calling Lapack should be as easy as calling any other DLL. You just have to figure out what link flags and statements to include in your build statement(s).
From Fortran you would, probably, declare as EXTERNAL the functions from Lapack that you wan't to use. This tells the compiler not to bother looking for a definition of the function in your sources, or in a mod file, but that the definition will be provided at link time. This is where the fun begins, as you try to ensure that the signatures of your calls match the signatures expected by the DLL.
I might be able to provide more help if you provide more information. What is your Windows development environment ? What Fortran compiler are you using ? What compile and link tools are you using ? What does your current link statement look like ?
Search terms: dynamic linking fortran
Take a look at this page:
http://sources.redhat.com/ml/binutils/2001-12/msg00471.html
It mentions using dlltool to generate a .a file from a .dll file. Presumably you should be able to link to that in the normal way (usually a lib switch on the compile command).
Otherwise, consider running a linux Live CD for the sake of avoiding the problem in the first place! If you're a student or an academic, see if you can find a server with fortran installed (the IT staff are usually pretty helpful) where you can compile and run your program.
Related
I have a third-party library which depends on libgcc_s_sjlj-1.dll.
My own program is compiled under MSYS2 (mingw-w64) and it depends on libgcc_s_dw2-1.dll.
Please note that the third-party library is pure binaries (no source). Please also note that both libgcc_s_sjlj-1.dll and libgcc_s_dw2-1.dll are 32-bit, so I don't think it's an issue related to architecture.
The outcome is apparent, programs compiled based on libgcc_s_dw2-1.dll can't work with third-party libraries based on libgcc_s_sjlj-1.dll. What I get is a missing entrypoint __gxx_personality_sj0.
I can definitely try to adapt my toolchain to align with the third-party's libgcc_s_sjlj-1.dll, but I do not know how much effort I need to go about doing it. I find no such variant of libgcc dll under MSYS2 using this setjmp/longjmp version. I am even afraid that I need to eliminate the entire toolchain because all the binaries I had under MSYS2 sits atop this libgcc_s_dw2-1.dll module.
My goal is straightforward: I would like to find a solution so that my code will sit on top of libgcc_s_sjlj-1.dll instead of libgcc_s_dw2-1.dll. But I don't know if I am asking a stupid question simply because this is just not possible.
The terms dw2 and sjlj refer to two different types of exception handling that GCC can use on Windows. I don't know the details, but I wouldn't try to link binaries using the different types. Since MSYS2 does not provide an sjlj toolchain, you'll have to find one somewhere else. I would recommend downloading one from the "MingW-W64-builds" project, which you can find listed on this page:
https://mingw-w64.org/doku.php/download
You could use MSYS2 as a Bash shell but you can probably not link to any of its libraries in your program; you would need to recompile all libraries yourself (except for this closed source third-party one).
I have some C code I would like to optimize. It turns out the Intel C Compiler (ICC) does a much better job at this than GCC but I don't have a copy of that compiler and it is very expensive. However, I can compile it using ICC and get the assembly online at godbolt.org.
If I copy and paste this assembly into a text file, how can I then convert it into a functioning executable?
You will need to begin by making sure that the runtime environment for which godbolt.org compiles is similar enough to your runtime environment, (good luck with that,) because for example you may be using windows, and godbolt.org may be using linux, (or the other way around,) so when you bring the assembly to your system you might be able to convert it to object code, but it will still not link and it will not run.
Then you will need to find an assembler for your platform which is compatible with the syntax of assembly produced by the intel C compiler of godbolt.org so as to produce object files from the assembly files. (Good luck with that.)
Then you will need to find any and all runtime libraries (redistributables) required by code produced by the intel C compiler. (Good luck with that.)
Finally you will need to obtain a linker to link your resulting object files with the runtime libraries to produce an executable. (Good luck with that.)
Sometimes we need honest answers to our questions just so that we can realize how impossible our ideas are.
Perhaps it's just better to describe my problem.
I'm developing a Haskell library. But part of the library is written in C, and another part actually in raw LLVM. To actually get GHC to spit out the code I want I have to follow this process:
Run ghc -emit-llvm on both the code that uses the Haskell module and the "Main" module.
Run clang -emit-llvm on the C file
Now I've got three .ll files from above. I add the part of the library I've handwritten in raw LLVM and llvm-link these into one .ll file.
I then run LLVM's opt on the linked file.
Lastly, I feed the LLVM bitcode fileback into GHC (which pleasantly accepts it) and produces an executable.
This process (with appropriate optimisation settings of course) seems to be the only way I can inline code from C, removing the function call overhead. Since many of these C functions are very small this is significant.
Anyway, I want to be able to distribute the library and for users to be able to use it as painlessly as possible, whilst still gaining the optimisations from the process above. I understand it's going to be a bit more of a pain than an ordinary library (for example, you're forced to compile via LLVM) but as painlessly as possible is what I'm looking for advice for.
Any guidance will be appreciated, I don't expect a step by step answer because I think it will be complex, but just some ideas would be helpful.
I have a object file which has a main() function inside and just needs to be linked with crt... objects to be an executable . Unfortunately I can only compile and I can not link it to be an executable .
so I decided to create a c program ( on a pc with working GCC and linker ) to attach object(s) at the end of itself and execute the codes attached at run time (simulating a linked object ).
I saw DL API but I do'nt know how to use it for the problem I said .
May sb help me to know , how I can executing a code attached at the end of an executable .
Avoid doing that; it would be a mess .... And it probably won't reliably work, at least if the program is dynamically linked to the libc6.so (e.g. because of ASLR)
Just use shared objects and dynamically linked libraries (See dynamic linker wikipage). You need to learn about dlopen(3) etc.
If you really insist, take many weeks to learn a lot more: read Levine's book on Linker and Loaders, read Advanced Linux Programming, read many man pages (including execve(2), mmap(2), elf(5), ld.so(8), ...) study the kernel code for execve and mmap, the GNU libc and MUSL libc source codes (for details about implementations of the dynamic linker), the x86-64 ABI or the ABI for your target processor (is it an ARM?), learn more about the GNU binutils etc, etc, etc.
In short, your life is too short doing such messy things, unless you are already an expert, e.g. able to implement your own dynamic linker.
addenda
Apparently your real issue seems to use tinycc on the ARM (under Android I am guessing). I would then ask on their mailing list (perhaps contribute with some patch), or simply use binutils and make your own GNU ld linker script to make it work. Then the question becomes entirely different and completely unrelated to your original question. There might be some previous attempts to solve that, according to Google searches.
I think a major design flaw in Linux is the shared object hell when it comes to distributing programs in binary instead of source code form.
Here is my specific problem: I want to publish a Linux program in ELF binary form that should run on as many distributions as possible so my mandatory dependencies are as low as it gets: The only libraries required under any circumstances are libpthread, libX11, librt and libm (and glibc of course). I'm linking dynamically against these libraries when I build my program using gcc.
Optionally, however, my program should also support ALSA (sound interface), the Xcursor, Xfixes, and Xxf86vm extensions as well as GTK. But these should only be used if they are available on the user's system, otherwise my program should still run but with limited functionality. For example, if GTK isn't there, my program will fall back to terminal mode. Because my program should still be able to run without ALSA, Xcursor, Xfixes, etc. I cannot link dynamically against these libraries because then the program won't start at all if one of the libraries isn't there.
So I need to manually check if the libraries are present and then open them one by one using dlopen() and import the necessary function symbols using dlsym(). This, however, leads to all kinds of problems:
1) Library naming conventions:
Shared objects often aren't simply called "libXcursor.so" but have some kind of version extension like "libXcursor.so.1" or even really funny things like "libXcursor.so.0.2000". These extensions seem to differ from system to system. So which one should I choose when calling dlopen()? Using a hardcoded name here seems like a very bad idea because the names differ from system to system. So the only workaround that comes to my mind is to scan the whole library path and look for filenames starting with a "libXcursor.so" prefix and then do some custom version matching. But how do I know that they are really compatible?
2) Library search paths: Where should I look for the *.so files after all? This is also different from system to system. There are some default paths like /usr/lib and /lib but *.so files could also be in lots of other paths. So I'd have to open /etc/ld.so.conf and parse this to find out all library search paths. That's not a trivial thing to do because /etc/ld.so.conf files can also use some kind of include directive which means that I have to parse even more .conf files, do some checks against possible infinite loops caused by circular include directives etc. Is there really no easier way to find out the search paths for *.so?
So, my actual question is this: Isn't there a more convenient, less hackish way of achieving what I want to do? Is it really so complicated to create a Linux program that has some optional dependencies like ALSA, GTK, libXcursor... but should also work without it! Is there some kind of standard for doing what I want to do? Or am I doomed to do it the hackish way?
Thanks for your comments/solutions!
I think a major design flaw in Linux is the shared object hell when it comes to distributing programs in binary instead of source code form.
This isn't a design flaw as far as creators of the system are concerned; it's an advantage -- it encourages you to distribute programs in source form. Oh, you wanted to sell your software? Sorry, that's not the use case Linux is optimized for.
Library naming conventions: Shared objects often aren't simply called "libXcursor.so" but have some kind of version extension like "libXcursor.so.1" or even really funny things like "libXcursor.so.0.2000".
Yes, this is called external library versioning. Read about it here. As should be clear from that description, if you compiled your binaries using headers on a system that would normally give you libXcursor.so.1 as a runtime reference, then the only shared library you are compatible with is libXcursor.so.1, and trying to dlopen libXcursor.so.0.2000 will lead to unpredictable crashes.
Any system that provides libXcursor.so but not libXcursor.so.1 is either a broken installation, or is also incompatible with your binaries.
Library search paths: Where should I look for the *.so files after all?
You shouldn't be trying to dlopen any of these libraries using their full path. Just call dlopen("libXcursor.so.1", RTLD_GLOBAL);, and the runtime loader will search for the library in system-appropriate locations.