How to Convert 64bit COFF to OMF? - static-libraries

I need to convert a 64bit .lib file from COFF to OMF. Coff2Omf.exe works fine with 32bit libs but gives...
ERROR: COFF error: FOOx64.lib
(coffread.cpp, 1637) : invalid machine type detected
...on a 64bit lib.
Is there an updated tool or similar to use for this?

Per Embarcadero's documentation:
Differences Between Clang-based C++ Compilers and Previous-Generation C++ Compilers
Object and Library File Format
BCC32 and its associated tools use OMF in .obj and .lib files.
Clang-based C++ compilers use ELF in .o and .a files.
This difference means, for example, that when you migrate a 32-bit Windows applications you must change references to .lib and .obj files to be .a and .o, respectively.
BCC64.EXE, the C++ 64-bit Windows Compiler
Compiled object file
ELF64 format
#pragma link
Do not specify the file extension (.ext) of modulename, as long as you are using default file types. The linkers assume the following default values for the file extension (.ext) of modulename:
.obj extension for BCC32
.o extension for:
Clang-based C++ compilers
BCCOSX
So if you omit the .ext, then the correct extension is automatically used according to your current target platform.
OMF is only used by the 32bit compiler/linker. The 64bit compiler/linker uses ELF64 instead.

I wonder if OMF specification have ever existed for 64-bit architecture. By the way, why do you need 64-bit OMF files? 64-bit versions on C++Builder are based on LLVM compiler backend, which produces ELF object files (as far as i know)
I don't know if something like coff2elf is bundled with C++Builder XE7, but, probably you can use opensource tools, like "Object File Converter", look for it here:
http://www.agner.org/optimize/#objconv

Related

Question for GCC equation.com for building the using static

I like windows gcc equation.com because it like ran natively just like windows compiler. However :
I will need some dll's that not included on distributed package. if i compiled a windows equation.com gfortran program like using Openblas, it will need libgcc_s_seh-1.dll libgfortran-5.dll libquadmath-0.dll libwinpthread-1.dll.
I could find it on web. But how to make it statically linked, i saw libgcc.a libgfortran.a libquadmath.a libpthread.a so i dont have to copy the dll from other. It is possible ?
For several c source code it need include <sys/resource.h> that not included. It's compatible with resource.h from where. After just copied from others, and recompile.
I got error :
c:\gcc\x86_64-w64-mingw32\include\sys\resource.h:74:29: error: unknown type name 'id_t'; did you mean 'pid_t'?
Is there any forum for this type gcc? Is there any debugger for windows gcc that friendly like VisualStudio Community for Intel Fortran.
Regards.

Link a Windows .exe with other Fortran routines on Linux

I have a Fortran ".exe" file generated in Windows. I want to link it with other Fortran routines while compiling on Linux platform.
For example, I have "a.exe" file generated on Windows. I wrote "b.f90" and "c.f90" on linux machine. I want to compile "b.f90" and "c.f90" and link them to "a.exe" to generate the final ".exe" file.
Is it possible?
No, it is not possible.
(Or it would be very very complicated and the .exe would have to be specially prepared for that.)
Not only Linux and Windows executables are incompatible. You do not link an .exe with anything, not on Windows, not on Linux, nowhere (except linking with the .dll or .so dynamic libraries the executable always requires). What you normally do is that you compile your Fortran or other language sources to object files and then you can link the object files to form a library (dynamic or static) or to form an executable.
What you could theoretically do, IF the .exe file already requires some .dll libraries, or is able to load some on request, is to compile your .f90 files to make these .dll libraries (somewhere with Windows or with a Windows compiler under Linux in Wine or with a cross-compiler) and then run everything under Linux using Wine. But I would just recompile everything on Linux from scratch.

Linking with C libraries on Windows with Dub

I am trying to link glfw on windows.
On Linux it was fairly straight forward:
dependency "derelict-glfw3" version="~>2.0.0"
subConfiguration "derelict-glfw3" "derelict-glfw3-static"
sourceFiles "deps/glfw/build/src/libglfw3.a" platform="posix"
libs"Xi" "pthread" "X11" "Xxf86vm" "Xrandr" "pthread" "GL" "GLU" "Xinerama" "Xcursor" platform="posix"
If I try to link with a .dll on windows, dub tells me that Error: unrecognized file extension dll.
dependency "derelict-glfw3" version="~>2.0.0"
subConfiguration "derelict-glfw3" "derelict-glfw3-static"
sourceFiles "deps\\glfw\\build\\src\\Debug\\glfw3.dll" platform="windows"
If I try to link with a .lib, dub tells me that COFF is not supported.
dependency "derelict-glfw3" version="~>2.0.0"
subConfiguration "derelict-glfw3" "derelict-glfw3-static"
sourceFiles "deps\\glfw\\build\\src\\Debug\\glfw3.lib" platform="windows"
GLFW was built with vs2013. What do I have to do differently?
There's three cases here:
Default 32 bit Windows build. dmd on Windows, by default, builds 32 bits using the old OMF linker format. You cannot link straight to a dll and need a .lib. But since it uses the old format, most .libs provided won't work - you have to make your own.
(lol i want this in the list item but markdown sucks. whatever)
Download this thing to get implib.exe: http://ftp.digitalmars.com/bup.zip
and use that to make a .lib from the .dll: implib /s yourdll.lib yourdll.dll and try to link with the new lib. (Add it to the files list like you are already doing)
If it doesn't work, try the command again, but this time without the /s switch.
It should work by then.
-m32mscoff 32 bit builds. With that flag to dmd, it will output a 32 bit program using the new COFF format instead of the old omf format. For it to work, link.exe in your path MUST be the Microsoft linker, from Visual Studio, instead of the default Digital Mars optlink.exe (which, confusingly, was also called link.exe until recently. That was nice when it was a compatible replacement for the Microsoft one.... twenty years ago...).
Anyway, if you have the Microsoft C++ compiler and linker installed and put that link.exe in your path, dmd -m32mscoff should work using existing .lib files from the dlls.
TIP: If you used the Windows installer for dmd, open the "D2 64 bit command prompt" from the start menu to get the path set up. It will tell you to use -m64, but you can also use -m32mscoff from that environment and it should work. if everything installed properly.
-m64 64 bit builds. Basically the same as the mscoff switch - you need the Visual C++ linker in your path - but does 64 bit instead of 32. Of course, this requires a 64 bit dll and lib to be there too.
In the comments, it sounds like you might also be facing some bugs, I don't know about that, the above is if everything else is working properly.

Mono on Mac: DllNotFoundException despite SQLite.Interop.dll being in dllmap

I have a C# application that uses SQLite and works fine on Windows.
The same Visual Studio project compiles fine in Xamarin Studio, but when running I get:
DllNotFoundException: SQLite.Interop.dll
Despite:
libsqlite3.0.dylib is in /usr/lib and also in the same folder as the executable and other DLLs
. is part of the $DYLD_LIBRARY_PATH
The executable and all SQLite-using DLLs have a matching <the_exe_or_dll_including_filename_extension>.config file containing:
<configuration>
<dllmap dll="sqlite" target="libsqlite.0.dylib" os="osx"/>
<dllmap dll="sqlite3" target="libsqlite3.0.dylib" os="osx"/>
</configuration>
I also tried adding <dllmap dll="SQLite.Interop.dll" target="libsqlite3.0.dylib" os="osx"/>, not better.
What is the problem?
You can easily find where mono is looking for that native library by setting the MONO_LOG_LEVEL to debug and MONO_LOG_MASK filtering to only DLL related messages.
export MONO_LOG_LEVEL=debug
export MONO_LOG_MASK=dll
mono yourprogram.exe
or as a one liner so you do not have to unset env vars:
MONO_LOG_LEVEL=debug MONO_LOG_MASK=dll mono yourprogram.exe
Mono and the OS-X dynamic link editor ('man dyld' for details) does not require DYLD_LIBRARY_PATH to be set to the current directory ('.'). Note: Linux does require LD_LIBRARY_PATH to include the current directory, if that is your intention.
Move those dll map files out of the way to remove them from the equation.
Unset DYLD_LIBRARY_PATH
cd in the directory that contains your CIL based exe, dlls and native dylib(s)
MONO_LOG_LEVEL=debug MONO_LOG_MASK=dll mono yourprogram.exe
Using the native dll/shared library trace output you can track which library is not being found (or one of its dependancies) or if it is the wrong ARCH for your mono version.
If you are still having problems, we would need to know which SQLite library you are using the options that you are using to compile it (or the arch version if getting it via a Nuget). A posting your dll trace output would quickly solve things also.
Notes:
I am assuming you are using the System.Data.SQLite library and are compiling the the options "/p:UseInteropDll=true /p:UseSqliteStandard=false".
Mono includes a SQLite in it's default install, it is 32-bit on OS-X:
file /Library/Frameworks/Mono.framework/Versions/4.0.2/lib/libsqlite3.dylib
/Library/Frameworks/Mono.framework/Versions/4.0.2/lib/libsqlite3.dylib: Mach-O dynamically linked shared library i386
Assuming you are using the OS-X package installer from Mono, thus are getting the 32-bit version of Mono and thus need 32-bit versions of the native libraries.
>>file `which mono`
/usr/bin/mono: Mach-O executable i386
The /usr/lib/libsqlite3.0.dylib is a multi ARCH fat binary, so that library is not a problem, but your debug output might show another one that is a problem,
>>file /usr/lib/libsqlite3.0.dylib
libsqlite3.0.dylib: Mach-O universal binary with 3 architectures
libsqlite3.0.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
libsqlite3.0.dylib (for architecture i386): Mach-O dynamically linked shared library i386
libsqlite3.0.dylib (for architecture x86_64h): Mach-O 64-bit dynamically linked shared library x86_64
You need to build and supply SQLite.Interop.dll (or more precisely libSQLite.Interop.dylib). The Mono distribution packages don't include it, probably because it's native code and really needs to be built on the target platform.
System.Data.SQLite on Windows uses a mixed mode approach (Managed data adapter + sqlite native code in one assembly). Mono however doesn't really support mixed mode assemblies.
So on MacOS there are two alternatives when it comes to building System.Data.SQLite on Windows:
Use interop dll.
Use libsqlite.x.x.dylib.
Both of these are native code and need to be built on the Mac.
Interop is Windows com speak so it's a bit disconcerting to see it used in a MacOS context. What this native dll is is the sqlite source code compiled up with some additional native code that can be P\Invoked by System.Data.SQLite. There are some benefits to using the interop dll as opposed to the sqlite dylib.
System.Data.SQLite ships with a copy of the relevant SQLite native source code in ./SQLite.Interop/src.core. You can build the interop library by running compile-interop-assembly-release.sh on the Mac. This will build libSQLite.Interop.dylib. Drop that in beside System.Data.SQLite and you should be good to go.
If you turn on Mono dll tracing you can watch the loader (see mono 4.8.0 loader.c) searching for the dll in various locations and with various name substitutions. Eventually it finds our dylib. It is also possible to use a dllmap entry in the System.Data.SQLite.dll.config file to direct the runtime to the dll. In my case Mono is on my app bundle so I have:
<dllmap dll="SQLite.Interop.dll" target="#executable_path/../Mono/libSQLite.Interop.dylib" os="!windows"/>
The dllmap target argument is passed to dlopen() so #executable_path et al are all usable.
I prefer this approach as it goes into the repo and provides some insight into what is going on when there's a foul up.

How to link elf static libs in llvm?

I have a lib (*.a) file, created with armcc in the elf format. There is no possibility to recompile it with llvm or gcc. (It's assembler written for armcc).
Linking it with the gnu ld works fine on Linux, but I have problems doing it on Mac, with llvm.
Because of the different internal format for obj files, it will say "Ignoring file ... which is not the architecture being linked"
Is there a workaround for this? A way to convert elf to Mach-O format? To tell llvm about elf?
There is such a tool for x86/86-64, written by Agner Fog, but I am looking for an ARM tool.
There is an objcopy from binutils, which should convert binary from one format to another. I think, you should have binutils compiled with both Linux and iOS BFDs. Unfortunately, binutils's support of Mach-O was incomplete (there are some negative reports about ARM+objcopy+Mach-O).
See also:
An objcopy equivalent for Mac / iPhone?
http://sourceware.org/bugzilla/show_bug.cgi?id=10222
Other way of converting is to do a reassembly (disassemble each .o file from .a archive and reassemble it with Mach-O-compatible assembler).

Resources