Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Linking ifort to g++ on Windows

Beliavsky
Beginner
633 Views

For normal_array.cpp

// https://people.duke.edu/~ccc14/sta-663-2018/notebooks/S12_CPP_Annotated.html

#include <random>
#include <functional> // needed for bind
extern "C" void normal_vec(int seed, int n, double x[]);

using std::default_random_engine,std::normal_distribution, std::bind;

void normal_vec(int seed, int n, double x[]) {
	// start random number engine with fixed seed
	default_random_engine re{seed};
	normal_distribution<double> norm(0,1); // mean and standard deviation
	auto rnorm = bind(norm, re);
	for (int i = 0; i<n; ++i) x[i] = rnorm();
}

 and xnormal.f90

program random_normal
use iso_c_binding
implicit none
!
interface
subroutine normal_vec(seed, n, x) bind(c)
import c_int, c_double
integer(kind=c_int), intent(in), value :: seed, n
real(kind=c_double)                    :: x(n)
end subroutine normal_vec
end interface
!
integer :: seed
integer, parameter :: n = 5
real(kind=c_double) :: x(n)
!
do seed=1,3
   call normal_vec(seed,n,x)
   print "(*(1x,f7.4))",x
end do
end program random_normal

I can compile and link on WSL2 with

g++ -c normal_array.cpp
ifort -c -o xnormal.o xnormal.f90
ifort normal_array.o xnormal.o

Trying that on Windows gives

normal_array.o : fatal error LNK1143: invalid or corrupt file: no symbol for COMDAT section 0x5

How should I compile and link on Windows?

0 Kudos
5 Replies
mecej4
Honored Contributor III
617 Views

 

cl /std:c++17 /c normal_array.cpp
ifort xnormal.f90 normal_array.obj

 

0 Kudos
Beliavsky
Beginner
595 Views

Thanks @mecej4 , that works for me, but I would still like to know how to do it with the g++ compiler.

0 Kudos
mecej4
Honored Contributor III
577 Views

As Steve wrote, in general mixing objects from different compilers (in fact, compilers from different stables) will not work, because Ifort compiled objects will have dependencies on MS C/C++ libraries, and G++ compiled objects will depend on GNU libraries, with a lot of duplicated entry points between the two sets. 

In this rather simple example, there is only one entry point needed, and the following steps worked when I used Cygwin G++.

 

g++ -shared -fPIC normal_array.cpp -o normal_array.dll
lib /def:normal_array.def /machine:x64
ifort xnormal.f90 normal_array.lib

 

where normal_array.def contains

 

LIBRARY NORMAL_ARRAY.DLL
EXPORTS
normal_vec

 

You can reduce the size of the DLL by adding the option -s to the g++ command line.

Steve_Lionel
Honored Contributor III
585 Views

It may not be possible. You'd end up with a mix of g++ and MSVC library code in there, and bad things might happen. 

0 Kudos
Steve_Lionel
Honored Contributor III
567 Views

Yes, isolating one or the other in a DLL is a good way to avoid some of these incompatibilities. 

0 Kudos
Reply