Topic: Bug in the Makefile creation for DLL

I want to build a shared library (DLL) using SF-2.2, so in the project options, the "shared library" is checked.
But I got some errors (library not found) to link some object files in order to build a shared library (DLL),
depending on other DLLs. I'm sure that the PATH for the library is set and that the others DLLs are in the true location.

Inspecting the Makefile created, I observed that the link step, at the bottom of the Makefile, contains both
the '-shared' and '-static' flags.
Removing the '-static' flag by hand fix the problem and all the other DLLs are found and then the shared library
is created.

This new bug has been found in the 2.2 (not in the 1.45, as far as I think).

Re: Bug in the Makefile creation for DLL

Same thing as above to build the executable when linking with DLLs.
I must remove the '-static' flag in order to get a successful link.

Re: Bug in the Makefile creation for DLL

Could you post the errors listing which libraries cannot be found when building the DLL?

The -static flag was added on purpose alongside the -shared flag to force statically linking the GNU Fortran runtime library into the DLL.  It was added to fix bugs other users were experiencing.

Jeff Armstrong
Approximatrix, LLC

Re: Bug in the Makefile creation for DLL

Consider a simple example of two DLLs : libone and libtwo. Files are stored in separated folders and each one
has a project file.

The first DLL is of course successfully created:
"C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\gfortran.exe" -c -o "build\libone.o" -m32 -Jmodules "libone.f90"
"C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\gfortran.exe" -o "libone.dll" -shared -static -m32 "build\libone.o" -LC:/PROG~5P2/SIMP~CHN/MING~DAW/lib/

The second files libtwo.f90 depends on libone.f90 (via modules and subroutine calls), so in the project properties :
     "..\libone\modules" has been added to the "Include/Module Directories"
and
     "..\libone" has been added to the "Librairies Directories"

Then, hereafter is the creation of libtwo.dll:
"C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\gfortran.exe" -c -o "build\libtwo.o" -m32 -IZ:/home/ecanot/tmp/workspace/SimplyFortran/essais/dynamic/libtwo/../libone/modules  -Jmodules "libtwo.f90"
"C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\gfortran.exe" -o "libtwo.dll" -shared -static -m32 "build\libtwo.o" -LC:/PROG~5P2/SIMP~CHN/MING~DAW/lib/ -LZ:/home/ecanot/tmp/workspace/SimplyFortran/essais/dynamic/libtwo/../libone -lone
c:/program files (x86)/simply fortran 2/mingw-w64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lone
collect2.exe: error: ld returned 1 exit status
Error(E42): Last command making (libtwo.dll) returned a bad status
Error(E02): Make execution terminated

Besides, if I remove the '-static' flag from the libtwo Makefile:
"C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\gfortran.exe" -o "libtwo.dll" -shared -m32 "build\libtwo.o" -LC:/PROG~5P2/SIMP~CHN/MING~DAW/lib/ -LZ:/home/ecanot/tmp/workspace/SimplyFortran/essais/dynamic/libtwo/../libone -lone

* Complete *

Re: Bug in the Makefile creation for DLL

I forgot to say that I'm testing SF-2.2 under linux via the wine loader, not directly under windows.

Usually, I'm developping under linux with all the GNU tools and with my own Makefiles.

Re: Bug in the Makefile creation for DLL

Okay, I see why you're having the issue.  Your library flag in the libtwo project is:

-lone

The compiler, with the -static flag set, is looking for a file named libone.a.  Apparently, if you remove the -static flag, it will instead use libone.dll if anything, which is actually a bit of a surprise to me.

Anyway, the ideal solution is to generate an import library while building the DLL.  Simply Fortran probably should do this by default, but it currently doesn't.  We ideally want to create a file libone.dll.a that will merely contain the declaration of exported symbols in libone.dll.  To do so, load your libone project and open the Project Options dialog.  In the Linker text field under Project Flags, add the following:

-Wl,--out-implib=libone.dll.a

That first part is "capital double-U el," and it instructs gfortran to pass along the flag after the comma to the linker directly.  Now clean and rebuild your libone project.  If you navigate to that directory, you should now see a libone.dll and libone.dll.a.

Next, open your libtwo project.  Open the Project Options dialog and change your library flag from:

-lone

to:

-lone.dll

Clean and rebuild your project, and everything should work fine.

The above method is actually how most GNU-compiled DLLs are linked to under Windows.  The GTK+ project is a good example.  In their lib directory are an assortment of "libgtk-2.0.dll.a" and similar files.

The above should fix your issue, although it is not necessarily ideal.  I think Simply Fortran should allow for two things:

1. Import libraries should be created by default when building DLLs

2. Users should be able to optionally disable static linking

Let me know if this solution works out.    It's good to hear someone is using Simply Fortran under WINE.  A reasonable amount of Simply Fortran's development takes place under WINE using Simply Fortran itself as the IDE.  The only real issue I've come across is the Start screen not loading properly.  If you do see any other problems under WINE, please don't hesitate to post them.

Jeff Armstrong
Approximatrix, LLC

Re: Bug in the Makefile creation for DLL

"Apparently, if you remove the -static flag, it will instead use libone.dll if anything, which is actually a bit of a surprise to me." ?
Not so surprising... under linux, the standard mechanism of loading libraries, when specifying '-lone' is first to find a libone.so file
(shared library) and then to find a libone.a file (static library).

I'll add some comment later on, about the size of the executable.

Re: Bug in the Makefile creation for DLL

True, I hadn't considered the default behavior on GNU/Linux, and I suppose on Windows, it will simply replace the .so extension with .dll.  That said, the general "preferred" route under Windows is to use import libraries when dealing with linking to DLLs.  As I pointed out, the GTK+ libraries do so, and I know from experience that Python uses the same technique under Windows.

I've had complaints about the size of executables and libraries created by Simply Fortran before, and, of course, it is due to statically linking the GNU Fortran runtime library to the targets.  However, the size is not anything close to problematic on today's modern hard disks, and it eliminates two possible issues.  First, it gets rid of the need to further contaminate the system path with the compiler's internal library directory.  Second, it allows programs built with Simply Fortran to be shared with others without having to hunt down the GNU Fortran and GCC runtime DLLs.

The tradeoff is a few hundred kilobytes of disk space for a little more ease of use and fewer headaches.

Jeff Armstrong
Approximatrix, LLC

Re: Bug in the Makefile creation for DLL

Size of files is important when creating a number of executables to test a library. In my case (MUESLI library), when using static libraries under linux, each executable may have its size up to 20 Mb, even if the main program file is very small. So the use of shared libraries is required and unavoidable to build small executables.

Let's consider the two following ways (taking again my previous example of libone+libtwo+executable):

  1. the removing of the -static flag in the Makefile, before building the executable

  2. the use of an import library for each DLL

Sizes obtained are the following ones:

  1. libone.dll=56.5 kB, libtwo.dll=59.7 kB, exe=66.4 kB

  2. libone.dll=64.1 kB, libtwo.dll=346.7 kB, exe=73.8 kB

For libtwo, it looks like the presence of the -static flag has forced to include many symbols (libgfortran ?, ...). Ok, the two executables have a similar size but, in my case, I prefer use the first method (even it is annoying to modify the Makefile each time) because I am working with a long chain of dependant libraries (arpack, blas, lapack, suitesparse, libz, fml).

Anyway, thank you for all your detailed explainations.
Perhaps the addition of a new option disabling the -static flag is a good idea...

Considering the use of SF under linux, I'm using the wine package provided for ubuntu-13.04: it is wine-1.4.1, released on march 2012 if I'm not wrong. Latest stable version of wine is 1.6, released on july 2013, but I don't use it.
All things work, even the splash screen, but I must launch SF (the fwin.exe executable actually) by clicking on any project file, not on the SF icon installed on the desktop. I never tried to use the debugger in the 2.2 version. But an annoying thing is that the executable cannot be launched inside the IDE. I have to open a terminal, cd to the folder containing the executable and typing "./my_prog.exe", then the program is automatically run via wine. In the case where DLL are used, they must be all copied (or soft linked under linux) in the same location.

Re: Bug in the Makefile creation for DLL

Sorry, when typing my comment at 17:05, I didn't see yours at 15:04 ...

Re: Bug in the Makefile creation for DLL

I appreciate your input here concerning the static linking.  I plan on adding an option in the next version to enable/disable the static flag.  You are correct that having multiple DLLs all including their own copies of the GNU Fortran runtime is not particularly efficient.  In cases where you're linking maybe one DLL, it is useful, especially if you're linking to a Simply-Fortran-created DLL from another language, Visual Basic for example.  If you're building multiple DLLs with Simply Fortran and then linking everything to a Simply-Fortran-created executable, the static linking is entirely unnecessary.

The next version will include an option to disable the static linking option on a per-project basis.

I'll also make sure all launch options work properly under GNU/Linux and WINE.  WINE tends to deal with handles to consoles a bit differently than true Windows, so that might be what you're experiencing.

Jeff Armstrong
Approximatrix, LLC

Re: Bug in the Makefile creation for DLL

Jeff, for your information, I just tried this evening SF-2.3 with wine-1.7.1:

  • as before, SF cannot be launch by clicking on the desktop icon; but clicking on any project file launches it.

  • once built, the program can be executed inside the IDE (contrary to wine-1.4.1) by typing F5. Input values may be entered in the bottom bar, after clicking to the send button.

  • the debugger seems to work properly, at least for a small test program of 20 lines. Stepping between lines works. Input/Output are done in a separated window.

Regards,
Édouard

Re: Bug in the Makefile creation for DLL

Édouard,

That's great to hear!  I'll look into possibly making the desktop icon optional (since it doesn't work properly on my Debian GNU/Linux desktop either), and, of course, 2.4 will allow optionally switching off the static linking.

-Jeff

Jeff Armstrong
Approximatrix, LLC

Re: Bug in the Makefile creation for DLL

Édouard,

Version 2.4 is now available, and it allows enabling/disabling static linking in Project Options.  It will continue to provide static linking by default, but it can be easily disabled now.

Jeff Armstrong
Approximatrix, LLC

Re: Bug in the Makefile creation for DLL

I just saw the new version this evening.

Many thanks.