Cross-compiling from WSL and Linux causes missing entry point DeleteCriticalSection - linux

I'm trying to cross-compile from WSL and Linux to Win32 using i686-w64-mingw32-gcc. The program is dependent on some DLL:s that I have downloaded, and are known to work when used for an exe cross-compiled on Cygwin. Compilation and linking works without throwing any errors or warnings, but when I run the resulting executable on Windows (by double-clicking on it in an Explorer window) I get a Windows-error-prompt:
The procedure entry point DeleteCriticalSection could not be located in the DLL...
and then it points to the program (the .exe) itself, not a DLL (message translated from Swedish ;-).
When I do the exact same thing on Cygwin with the same archive for the DLL:s and the same DLL:s the resulting exe works as it should.
The new(ish) Dependencies shows some red lines for COMCTL32 and OLEAUT32, but those are the same for both.
A very simple windows GUI app compiles and runs, so it's not the cross-compile as such that is causing the issue. The DLL:s in combination with WSL/Ubuntu/GNU cross-compilation seems to be the culprit.
Instructions
EDIT: after explicitly following my own instructions and explicitly re-installing the cross-compilation tool-chain the instructions below no longer creates a faulty exe. But the original problem remains.
I'm happy to take any ideas on what to try next.
Here are instructions to repeat what I have. Create an empty directory in WSL and run
$ sudo apt install binutils-mingw-w64-i686 gcc-mingw-w64-i686
$ wget https://github.com/DavidKinder/Windows-Glk/releases/download/1.50/WindowsGlk-150.zip
$ unzip WindowsGlk-150.zip
Then create startup.c with the following content
#include <unistd.h>
#include "glk.h"
#include "WinGlk.h"
int winglk_startup_code(const char* cmdline)
{
return 1;
}
void glk_main(void) {
sleep(10);
}
(Fix the capitalized include of "glk.h" in Glk.c or you'll get an error.)
Compile and link with
$ i686-w64-mingw32-gcc -mwindows -I Include/ Glk.c startup.c Glk.lib
to get an a.exe. The message only shows up in Gui-mode so you need to run it from an explorer window:
explorer.exe .
and double-click on a.exe.
WSL and Linux vs. Cygwin
I've done the same cross-compilation on a "real" Ubuntu 20.04 and getting the same problem. Again, doing the exact same steps in Cygwin produces a runable exe. This points to a cross-compilation problem with some facet of
what the exe and the DLL:s are doing. (There is no code in the exe that does anything with critical sections. Could this be an API mismatch?)
Since the DLL:s are the same it is reasonable to suspect the actual cross-compilation of sources in my program.
Is there anything in the cross-compilation toolchain on Linux that might differ? Which Windows run-times and API-versions are targeted?
I'm happy to take any ideas on what to try next.

Related

Undefined reference under WinMain#16 in cygwin

i am new to stackflow and i previously i have no background in computer system and programming. However, now i need to run analysis under cygwin for my bioinformatics project. I encounter some error when i try to compile a file name 'zone_b.linux'using cygwin, to produce an executable program. The linux file is download from web https://github.com/haddocking/HADDOCK-binding-sites-tutorial/blob/master/ana_scripts/zone_b.linux. When i try to compile using the following command under cygwin it produce the following error:
$ gcc zone_b.linux
/usr/lib/gcc/i686-pc-cygwin/6.4.0/../../../libcygwin.a(libcmain.o): In
function `main':
/usr/src/debug/cygwin-2.9.0-3/winsup/cygwin/lib/libcmain.c:37: undefined
reference to `WinMain#16'
collect2: error: ld returned 1 exit status
Error description
I search the following error under stackoverflow, and i found two post with similar problem.
First is the post from undefined reference to `WinMain#16'. It stated that the problem is due the Microsoft'linker uses a runtime library entry point(winMainCRTStartup) that calls Microsoft's non-standard WinMain instead of standard main. So, i try the post's suggestion of including the entry by following command
$ gcc zone_b.linux /entry:winMainCRTStartup
gcc: error: /entry:winMainCRTStartup: No such file or directory
However i get the error no such file or directory. I think maybe it is because i am running under cygwin not mingW.
Second post is the Undefined reference to WinMain in Cygwin. From the post, it said use -c compile flag to only produce object file. However, for my case, i am not using any -c. Therefore, i think it is not relevant to my issue.
I would appreciate if anyone could kindly explain to me since i am new to this computing area. Thank you.
zone_b.linux is the compiled and linked executable program to run on a linux machine. It is a 32-bit ELF binary file. It will not work on a Windows machine, even using cygwin or mingw32, without re-compulation.
You probably have to compile zone_b.f, a FORTRAN source file, using the gfortran compiler to create a zone_b.exe that is usable in cygwin. I saw no instructions for this, but try something like gcc zone_b.f and cross fingers. Be sure gfortran is installed using cygwin setup.
You will also need to (re-)build the other executables (cluster_struc and contact) by performing make in the ana_scripts directory. Any supplied executables (from the git clone ... or a downloaded .zip file) will not work under cygwin.
You will need to have perl and python installed. I think perl is installed by default. You can install python2 using cygwin setup. The python script looked like it will work with python2 or python3, whichever is the default. On cygwin, today, python2 is the default python. I don't do perl, so cross your fingers.

Call Matlab from Intel Fortran (Linux)

I am trying to integrate a Matlab program I wrote into some Fortran code. I tried to follow the example Mathworks provides. But I can't get it to compile because I can't find the header files it requests.
Does anyone know of an example of someone getting it to work on Linux using an Intel compiler. I think that might be part of the problem because Matlab only supports GNU Fortran on Linux.
And I realize this is a simple question, I just don't understand how to do anything in compiling more complicated than including multiple files with defined paths.
Disclaimer: I'm currently using OS X so I can only provide output from OS X but everything should transfer easily over to Linux due to the Unix base. I also don't have the Intel Fortran compiler on OS X (only the C/C++ compiler).
Note: You will need to substitute the paths I use for the correct paths on your system depending on your MATLAB installation directory.
This issue isn't specific to the Intel Compiler, I also receive errors with the GCC Fortran compiler.
$ gfortran fengdemo.F
fengdemo.F:1:0:
#include "fintrf.h"
^
Fatal Error: fintrf.h: No such file or directory
compilation terminated.
You can use the Unix locate command to find files.
$ locate fintrf.h
/Applications/Matlab R2014a.app/extern/include/fintrf.h
In the directory where fengdemo.F is we can then pass the correct directory in using the -I option
-I../../include/
However, this produces linking errors as we haven't specified where the libraries for fintrf.h can be found. We can do this with the -L option (you will need to replace maci64 with the correct option for Linux - I can't remember it off the top of my head but you should be able to see it in the bin directory)
-L../../../bin/maci64/
Now we need to tell it what libraries to use with -leng -lmx and so the completed command is
$ ifort fengdemo.F -I../../include/ -L../../../bin/maci64/ -leng -lmx
and it should compile correctly.
We aren't finished yet though as it won't execute. We need to set up our PATH and DYLD_LIBRARY_PATH environment variables correctly. Specifically we need to add the bin and bin/maci64 directories of our MATLAB installation to PATH
$ export PATH=$PATH:/Applications/Matlab\ R2014a.app/bin/maci64:/Applications/Matlab\ R2014a.app/bin
and the bin/maci64/ and sys/os/maci64/ to DYLD_LIBRARY_PATH
$ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/Applications/Matlab\ R2014a.app/bin/maci64/:/Applications/Matlab\ R2014a.app/sys/os/maci64/
Note: On Linux DYLD_LIBRARY_PATH should be LD_LIBRARY_PATH. Thanks to Vladimir F for correcting me.
Now you can execute the program using
$ ./a.out

Unable to make a portable Fortran executable in Cygwin

I'm attempting to compile a relatively simple Fortran executable so that it can be passed around to other Windows users that don't have Cygwin (or something of the sort) installed, however, I'm unable to get the executable to operate as a standalone. I've tried gfortran -static file.f and gfortran -static-libgfortran file.f, however other users always encounter this error:
The program can’t start because cygwin1.dll is missing from your computer. Try reinstalling the program to fix this problem.
From what I've read online (e.g. here), the -static option should be sufficient. I have verified that running the executable from my machine (DOS prompt) does work.
I have gcc (gfortran) version 4.7.3. I should also point out this is my first attempt at compiling portable Fortran.
Update
After realizing that this isn't a gfortran-specific issue (thanks to replies here), searches led me to related posts here and here
This is partially explained in the Cygwin FAQ. The solution is to install the mingw64-i686-gcc-fortran package with its dependencies, and cross-compile your code with i686-w64-mingw32-gfortran -static.
Just package the cygwin1.dll along with your binary file (both in the same folder) then it will run just fine.

g++ default header include list

While performing a compilation with cross g++ in a Linux machine ( lubuntu 11.10 ) in verbose mode, I can see the list of the default include header directories:
#include <...> search starts here:
/opt/eldk-4.2/usr/bin/../lib/gcc/powerpc-linux/4.2.2/include
/opt/eldk-4.2/ppc_4xx/usr/include/c++/4.2.2/opt/eldk-4.2/ppc_4xx/usr/include/c++/4.2.2/powerpc-linux
/opt/eldk-4.2/ppc_4xx/usr/include/c++/4.2.2/backward
/opt/eldk-4.2/usr/../ppc_4xx/usr/include
Executing the very same g++ binary in another Linux machine (lubuntu 12.10), I get another different list, with less elements:
#include <...> search starts here:
/opt/eldk-4.2/usr/bin/../lib/gcc/powerpc-linux/4.2.2/include
and in which some of the elments seem bad constructed, like the following:
ignoring nonexistent directory "/opt/ppc_4xx/usr/lib/gcc/powerpc-linux/includ../include/c++/4.2.2"
The result is that some code compiling on the first system is not compiling on the second because some headers are not found.
Why is this happening?. Where does this list come from?. Who is responsible for constructing it?. Is it possible to easily change it?.
Any help is appreciated.
You can add directories to the default search path by setting environment variables:
C_INCLUDE_PATH (for C header files)
CPLUS_INCLUDE_PATH (for C++ header files).
Alternatively, you can create and edit specfile and place it where G++ looks for them. You can check the path with strace gcc.
Additional documentation on specfiles on GCC page.
I have the exact some problem using ELDK 4.2. This is very likely connected to something that changed in ubuntu 12.04 as I have had the compiler run fine on the same computer before the upgrade.
My problem is that is seems to have forgotten /usr
ignoring nonexistent directory "/opt/eldk-4.2/../ppc_82xx/usr/include"
It should be
/opt/eldk-4.2/usr/../ppc_82xx/usr/include
Which works perfectly on ubuntu 11.10.
I have tried both installing ELDK from the ISO and copying the installation from a working version in ubuntu 11.10

Compiling Haskell code in Cygwin, and some other bugs in Haskell Platform on Windows

I am trying to compile a simple hello world program in Haskell, with Haskell Platform 2011.2.0.1. If I load the code in WinGHCi, and use the GUI to compile, the .exe is created. Then I can run the .exe from Cygwin.
But if I try to compile the code in Cygwin (using ghc --make), linker fails. But again, if I compile from the Windows cmd prompt, then the compile+linker works fine.
Are there any other environment variables I need to import into Cygwin, to make the compile+linker work in it? I have put the following dirs in my Cygwin PATH: 2011.2.0.1/lib/extralibs/bin, 2011.2.0.1/bin (these are the only two valid Haskell related entries that I could see in the Windows environment variables).
I also noticed a couple of invalid items in the Windows environment variables (this looks like a bug in the Haskell installation):
(system var) C/ProgramFiles/Haskell/bin - this dir does not exist because I have installed Haskell in D disk.
(user var) userxxx/ApplicationData/cabal/bin - this dir does not exist.
I tried to file a bug report in HaskellPlatform, but I dont have permission to do it.
Without access to your development environment or a listing of the errors that you're getting, I can only assume that the issue is related to the way that you've set up your PATH.
GHC on Windows comes bundled with its own gcc compiler (for C code) and ld linker. If you've installed Cygwin, you've probably also installed the MinGW toolchain, which comes with its own version of gcc and ld. Then, you've probably made your PATH variable list /usr/bin before the path to the Haskell Platform binary directories, which makes ghc find the MinGW linker and C compiler before it finds the versions that were bundled with GHC.
You need to make sure that the HP directories are listed before the Cygwin directories. It should not be like this:
$ echo $PATH
/bin:/usr/bin:.../2011.2.0.1/bin
Instead, it should be like this:
$ echo $PATH
.../2011.2.0.1/bin:/bin:/usr/bin
This is only a guess at what the issue might be, and you should provide more details for a better diagnosis.

Resources