Compile ARPACK x64 dll & lib For VS2005 On Windows 7 by Using MinGW64

CompileARPACKx64 dll & lib ForVS2005 OnWindows 7 by UsingMinGW64

 

                                                                Author : Zeng qiang Date : 2013-3-4

 

 To Use ARPACK functions with C/C++ in VS2005 x64 mode, I've tried many ways and all failed.

  By searching a lot of webs, trying for several days, finally I succeeded. OK, no more waste, Let's Begin.

Step 1 - Download and setupMinGW64 andMSYS.

  MSYS can get from the URL below(mingw-get-inst-20120426.exe)

      http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/mingw-get-inst-20120426/mingw-get-inst-20120426.exe/download

 (PS: MSYS is a console program which can use many Unix utilities on Windows. There is no 64 bits version of this collection of utilities because it is just a console and a set of tools to run bash instructions, no matter if they are 32 or 64 bits. Please make sure your Internet is work fine before setup!)

 Install the software under the directory

     D:\MinGW64

  When asked what components to install,only select the following:

     MSYS Basic System

     MSYS Developer ToolKit


 Once the install has finished, start the MinGW Shell

     D:\MinGW\msys\1.0\msys.bat

 For the convenience of using MSYS, input the command below in msys window to install a small tool which can help you use the MSYS:

    mingw-get install msys-rxvt


 This package is a graphical terminal. To use this terminal create a shortcut of the file msys.bat on the desktop and update the following properties:

     Target:D:\MinGW\msys\1.0\msys.bat --rxvt

     Start in:D:\MinGW\msys\1.0\bin


 Then get MinGW64 from the URL:

      http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/rubenvb/gcc-4.7-release/

 It's a 7z-package which include the GCC4.7.2 for 64 & 32 bits.

 The files I downloaded is:

*                           x86_64-w64-mingw32-gcc-4.7.2-release-win64_rubenvb.7z

 Uncompress the 7z-package into the D:\MinGW directory,

 You will find a sub folder in D:\MinGW:

          mingw64

 You can also setup the MinGW32 in the same way and you can find another sub folder "mingw32" !

 The MinGW32's URL is:

      http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/rubenvb/gcc-4.7-release/

 The files downloaded is:

*                          i686-w64-mingw32-gcc-4.7.2-release-win32_rubenvb.7z

 

 OK, Return the focus!!!

 Now in msys window, create the following additional directories:

     mkdir /d/mingw/local32

     mkdir /d/mingw/local64

 The two directories will be used to compile and install libraries and tool for 32 and 64 bits specific architectures.

 Then update the following configuration file to mount these directories automatically.

     D:\MinGW\msys\1.0\etc\fstab

 Add this content in the file above:

     D:\MinGW\                /mingw

     D:\MinGW\mingw32\   /mingw32

     D:\MinGW\mingw64\   /mingw64

     D:\MinGW\local32\       /local32

     D:\MinGW\local64\       /local64

 Remember to restart the terminal after the above changes.

 You can see the msys window changed:


 and now in D:\MinGW, you can see the folders below:


 Now create the following directories where we are installing common tools and configuration files.

     mkdir /local{32,64}/{bin,etc,include,lib,share,dst,src}

     mkdir /local{32,64}/lib/pkgconfig

 To compile 32 and 64 bits applications independently we must createtwo configuration files.

 Run the following command to create a configuration file for32 bits applications:

            cat > /local32/etc/profile.local << "EOF"
alias dir='ls -la --color=auto'
alias ls='ls --color=auto'
 
export PKG_CONFIG_PATH="/local32/lib/pkgconfig"
export CPPFLAGS="-I/local32/include"
export CFLAGS="-I/local32/include -mms-bitfields -mthreads -mtune=pentium3"
export CXXFLAGS="-I/local32/include -mms-bitfields -mthreads -mtune=pentium3"
export LDFLAGS="-L/local32/lib -lpthread -mthreads"
export PATH=".:/local32/bin:/mingw32/bin:/mingw/bin:/bin:/opt/bin:$PATH"
export PS1='\[\033[32m\]\u@\h \[\033[33m\w\033[0m\]$ '
 
export SRC_DIR=/local32/src
export DST_DIR=/local32/dst
export MINGW_HOME=/mingw32
export PKG_CONFIG=$DST_DIR/pkgconfig/bin/pkg-config.exe
 
# Configure PATH and FLAGS.
 
APPLICATION_ARRAY=(
"LIBICONV_PREFIX:$DST_DIR/libiconv"
"ZLIB_PREFIX:$DST_DIR/zlib"
"BZIP2_PREFIX:$DST_DIR/bzip2"
"LIBTOOL_PREFIX:$DST_DIR/libtool"
"LIBXML2_PREFIX:$DST_DIR/libxml2"
"LIBPNG_PREFIX:$DST_DIR/libpng"
"LIBJPEG_PREFIX:$DST_DIR/libjpeg"
"LIBTIFF_PREFIX:$DST_DIR/libtiff"
"FREETYPE2_PREFIX:$DST_DIR/freetype2"
"LCMS2_PREFIX:$DST_DIR/lcms2"
"FFTW_PREFIX:$DST_DIR/fftw"
"BOTAN_PREFIX:$DST_DIR/botan"
"QT_PREFIX:$DST_DIR/qt"
"OPENCV_PREFIX:$DST_DIR/opencv"
"LIBUSBX_PREFIX:$DST_DIR/libusbx"
"LIBFFI_PREFIX:$DST_DIR/libffi"
"PKGCONFIG_PREFIX:$DST_DIR/pkg-config"
"GETTEXT_PREFIX:$DST_DIR/gettext"
"GLIB_PREFIX:$DST_DIR/glib"
"GMQ8_PREFIX:$DST_DIR/gm-q8"
"GMQ16_PREFIX:$DST_DIR/gm-q16"
"IMQ8_PREFIX:$DST_DIR/im-q8"
"IMQ16_PREFIX:$DST_DIR/im-q16"
"BOOST_PREFIX:$DST_DIR/boost"
"LIBUSBX_PREFIX:$DST_DIR/libusbx"
"GLIB_PREFIX:$DST_DIR/glib"
"YAFARAY_PREFIX:$DST_DIR/yafaray"
)
 
for app in "${APPLICATION_ARRAY[@]}" ; do
 
    KEY=${app%%:*}
    VALUE=${app##*:}
    export "$KEY"="$VALUE"
    
    export PATH="$VALUE/bin:$PATH"
    export LDFLAGS="-L$VALUE/lib $LDFLAGS"
    export CFLAGS="-I$VALUE/include $CFLAGS"
    export CPPFLAGS="-I$VALUE/include $CPPFLAGS"
    export CXXFLAGS="-I$VALUE/include $CXXFLAGS"
    export PKG_CONFIG_PATH="$VALUE/lib/pkgconfig:$PKG_CONFIG_PATH"
 
done
 
export LIBFFI_CFLAGS="-I $DST_DIR/libffi/lib/libffi-3.0.11/include"
export LIBFFI_LIBS="-L$DST_DIR/libffi/lib"
 
EOF

 

    finish commands, you will find a "profile.local" file in your/local32/etc/ directory.

    Then run the following command to create a configuration file for64 bits applications:

  cat > /local64/etc/profile.local << "EOF"
 
alias dir='ls -la --color=auto'
alias ls='ls --color=auto'
 
export PKG_CONFIG_PATH="/local64/lib/pkgconfig"
export CPPFLAGS="-I/local64/include"
export CFLAGS="-I/local64/include -mms-bitfields -mthreads"
export CXXFLAGS="-I/local64/include -mms-bitfields -mthreads"
export LDFLAGS="-L/local64/lib -lpthread"
export PATH=".:/local64/bin:/mingw64/bin:/mingw/bin:/bin:/opt/bin:$PATH"
export PS1='\[\033[32m\]\u@\h \[\033[33m\w\033[0m\]$ '
 
export SRC_DIR=/local64/src
export DST_DIR=/local64/dst
export MINGW_HOME=/mingw64
export PKG_CONFIG=$DST_DIR/pkgconfig/bin/pkg-config.exe
 
# Configure PATH and FLAGS.
 
APPLICATION_ARRAY=(
"LIBICONV_PREFIX:$DST_DIR/libiconv"
"ZLIB_PREFIX:$DST_DIR/zlib"
"BZIP2_PREFIX:$DST_DIR/bzip2"
"LIBTOOL_PREFIX:$DST_DIR/libtool"
"LIBXML2_PREFIX:$DST_DIR/libxml2"
"LIBPNG_PREFIX:$DST_DIR/libpng"
"LIBJPEG_PREFIX:$DST_DIR/libjpeg"
"LIBTIFF_PREFIX:$DST_DIR/libtiff"
"FREETYPE2_PREFIX:$DST_DIR/freetype2"
"LCMS2_PREFIX:$DST_DIR/lcms2"
"FFTW_PREFIX:$DST_DIR/fftw"
"BOTAN_PREFIX:$DST_DIR/botan"
"QT_PREFIX:$DST_DIR/qt"
"OPENCV_PREFIX:$DST_DIR/opencv"
"LIBUSBX_PREFIX:$DST_DIR/libusbx"
"LIBFFI_PREFIX:$DST_DIR/libffi"
"PKGCONFIG_PREFIX:$DST_DIR/pkg-config"
"GETTEXT_PREFIX:$DST_DIR/gettext"
"GLIB_PREFIX:$DST_DIR/glib"
"GMQ8_PREFIX:$DST_DIR/gm-q8"
"GMQ16_PREFIX:$DST_DIR/gm-q16"
"IMQ8_PREFIX:$DST_DIR/im-q8"
"IMQ16_PREFIX:$DST_DIR/im-q16"
"BOOST_PREFIX:$DST_DIR/boost"
"LIBUSBX_PREFIX:$DST_DIR/libusbx"
"GLIB_PREFIX:$DST_DIR/glib"
"YAFARAY_PREFIX:$DST_DIR/yafaray"
)
 
for app in "${APPLICATION_ARRAY[@]}" ; do
 
    KEY=${app%%:*}
    VALUE=${app##*:}
    export "$KEY"="$VALUE"
    
    export PATH="$VALUE/bin:$PATH"
    export LDFLAGS="-L$VALUE/lib $LDFLAGS"
    export CFLAGS="-I$VALUE/include $CFLAGS"
    export CPPFLAGS="-I$VALUE/include $CPPFLAGS"
    export CXXFLAGS="-I$VALUE/include $CXXFLAGS"
    export PKG_CONFIG_PATH="$VALUE/lib/pkgconfig:$PKG_CONFIG_PATH"
 
done
 
export LIBFFI_CFLAGS="-I $DST_DIR/libffi/lib/libffi-3.0.11/include"
export LIBFFI_LIBS="-L$DST_DIR/libffi/lib"
 
EOF

    Ok, the two configuration files have been created.

    Finally default the configuration to 64bits when MSYS terminal is launched.(because we want to use the 64bits GCC tools to compile the ARPACK)

    Type the following commands to set the default configuration:

cat >> /etc/profile << "EOF"
if [ -f /local64/etc/profile.local ]; then
        source /local64/etc/profile.local
fi
 
EOF

    Those commands willappend some code to the end of the file "/msys/1.0/etc/profile" which used to configure the MSYS.

    And you can always switch between configurations running any of the following commands:

            source /local64/etc/profile.local
            source /local32/etc/profile.local

    Ok, now we finished the Step 1.

 

Step 2 - Download theARPACK andsetup.

    ARPACK is a collection of Fortran77 subroutines designed to solve large scale eigenvalue problems.

 You can download the ARPACK package from the URL:

    http://www.caam.rice.edu/software/ARPACK/index.html

 the file I downloaded is:

    arpack96.tar.gz

     patch.tar.gz

 Or you can search it from the Netlib Web:

      http://www.netlib.org/liblist.html

 After download the two files, and copy them to the "/local64/src" directory.

 Then launch the msys.bat, entering into the /local64/src directory.

    cd $SRC_DIR

       equals to the following commands:

    cd /local64/src

 Then uncompress the arpack96.tar.gz and patch.tar.gz:

     tar zxvf arpack96.tar.gz

     tar zxvf patch.tar.gz

    ls

 You can find a ARPACK folder like this:




     cd ARPACK

     ls


 Now let's modify some file:

    "ARmake.inc":

          home = D:/MinGW/local64/src/ARPACK

          FC = gfortran

          #FFLAGS = -O -cg89(disable this line)

     "UTIL/second.f" (change this file like below):

          SUBROUTINE SECOND(T)

          REAL T

          CALL CPU_TIME(T)

          RETURN

          END

 Ok, now we can compile the ARPACK under MinGW64 msys shell:

     cd /local64/src/ARPACK

     make lib

     dllwrap --export-all-symbols BLAS/*.o LAPACK/*.o SRC/*.o UTIL/*.o -lgfortran --output-def arpack_win64.def -o arpack_win64.dll

 Now you can find "libarpack_SUN4.a", "arpack_win64.def", "arpack_win64.dll" in your ARPACK directory like below:


 If you want to do aimplicit link with your dll, a lib file will be needed.

 Then you have to find your VS2005's lib.exe tool and add its path into the environment variables "PATH" so that we can use it in msys directly.

 The lib.exe's path(x64):

    C:\Program Files (x86)\Microsoft Visual Studio 8\VC\bin\amd64\lib.exe

(PS: My VS2005 is in the path "C:\Program Files (x86)\Microsoft Visual Studio 8",change that in your own way)

 If you want to use x86 32bits 's lib.exe, you can find it in the path:

     C:\Program Files (x86)\Microsoft Visual Studio 8\VC\bin\x86_amd64\lib.exe

 OK, assume that you already add the lib.exe to the system environment variables:


 Then restart the msys, and enter into your ARPACK directory, input those commands:

    lib /machine:X64 /def:arpack_win64.def

 Finish that, you can find a lib file in your ARPACK directory:

 

 It is"arpack_win64.lib"!

 Ok, now you have both arpack_win64.dll & arpack_win64.lib. Wait a moment, for your nomal running a C/C++ project linked with the dll & lib, you still need some other dll !!!

 You can download a tool named "Dependency Walker", then run and open the file "arpack_win64.dll", you can find some other dependency:

     libgfortran-3.dll


 This dll you can find it in the "D:/MinGW/mingw64/bin/" directory.

 Open the libgfortran-3.dll in Dependency Walker, you will find another two dependency dll:

     libquadmath-0.dll

     libgcc_s_sjlj-1.dll


    The two dll file also can find in mingw64/bin directory.

 (PS: if you were using 32bit x86's ARPACK dll & lib, you may need those three dll in mingw32/bin directory, the three dll have the same name with the mingw64/bin's dll, but in fact they are different.)

 Ok, now you only need to copy those file out of the ARPACK directory with your arpack dll & lib, and you can use them in your own way!

Step 3 -calling ARPACK's function inVS2005.

 After the step 2, you have those files:


 Then you can create a C++ project to call the functions in your compiled ARPACK library.

 I create a VC++ win32 project named "HelloARPACK".

 First, I copied the dll and lib file into it's directory.

 Then, I create a cpp file named HelloARPACK.cpp and add the following code :

          #include <stdio.h>

          

          #ifdef __cplusplus

          extern "C" {

          #endif

          

               double   dlapy2_(double *x, double *y);

          

          #ifdef __cplusplus

          }

          #endif

          int main(int argc, char **argv)

          {

               /*********************************/

               printf("Hello ARPACK dll&libx64 Test!\n");

               

               double myX=1.0;

               double myY=2.0;

               double myResult=0.0;

                

               myResult = dlapy2_(&myX,&myY);

                

               printf("myResult=%lf\n",myResult);

                

                /*********************************/

               

               getchar();

               return 0;

          }

 I add the lib into this project:


 Then Configure the debug/release mode:

           Builder->Configuration Manager:

                Active solution platform : x64

                Active solution configuration : debug or release

 (PS: The dll & lib generated from this method can be used in both debug and release mode! That is more convenience.)

 Then Build...

 That's great! We succeeded!

 You could scan the dlapy2's source code and know that this function is used to return a sqrt(x^2+y^2).

 I set x=1.0, y=2.0

 So the result in theory is sqrt(5)=2.2360679775...

 Let's check the result from our program!


 The result is:


 Cheers! The result is right!

 

 However, I want to used a modified fortran source code to compute the eigenvalue and eigenvectors, how can I do this?

 

 Don't worry, see the next Step!

 

Step 4 - callingARPACK function to compute theeigenvalues and eigenvectors.

 In ARPACK'sEXAMPLES directory, you will find several source which may be useful to you, now I need to solve a symmetric generalized problem described by Ax=λBx. the A matrix is symmetric, the B matrix is symmetric and positive-definite.

 In ARPACK/EXAMPLES/SYM/ directory, I found thedsdrv3.f is used to me, and I change the code to solve my problem.


 After change that, I want to calling dsdrv3.f by my C++ project ,I will transfer the A & B & other information into subroutine and wait for the return the eigenvalues and eigenvectors.

 So, I decide to compile this dsdrv3.f in my arpack_win64.dll & lib and calling directly!

 Then I must do some configuration and compile!

  First, copy the changed dsdrv3.f into the ARPACK/SRC.

 Second, open and modify the ARPACK/SRC/Makefile, find "DOBJ = d***.o..." position and add "dsdrv3.o" at the end of it:


 Third, enter into the /ARPACK, and make lib:

    cd /local64/src/ARPACK

     make lib

     dllwrap --export-all-symbols BLAS/*.o LAPACK/*.o SRC/*.o UTIL/*.o -lgfortran --output-def arpack_win64.def -o arpack_win64.dll

    lib /machine:X64 /def:arpack_win64.def

    OK, now you have finished the compile and got the new dll & lib.

Loot into the new arpack_win64.dll by using Dependency Walker:


 Now you could see dsdrv3_ !!!

 in the dsdrv3.f, my subroutine interface is:

          subroutine dsdrv3(row,col,vv,dvalue,a_mat,b_mat,binv_mat)

          integer row, col

          Double precision vv(row*col),dvalue(col),a_mat(row*row),

        &                     b_mat(row*row), binv_mat(row*row)

 

 Then I plan to used it in my "HelloARPACK" project.

 First, Update my arpack_win64.dll & lib.

 Then, change the code in cpp file to test the dsdrv3_ function:

          #include <stdio.h>

          #ifdef __cplusplus

          extern "C" {

          #endif

               void      dsdrv3_(int *row, int *col, double *vv, double *dvalue, double               *a_mat, double *b_mat, double *binv_mat);

          

          #ifdef __cplusplus

          }

          #endif

          

          #define mySIZE 3

          int main(int argc, char **argv)

          {

               /**********************************************/

               printf("now test dsdrv3.f!\n");

                

               double myA[mySIZE*mySIZE]={2,1,3,1,4,7,3,7,5};

               double myB[mySIZE*mySIZE]={1,0,0,0,1,0,0,0,1};

               double myB_inv[mySIZE*mySIZE]={1,0,0,0,1,0,0,0,1};

               double myvv[mySIZE*mySIZE];

               double mydvalue[2*mySIZE];

               int myRow=mySIZE;

               int myCol=mySIZE;

                

               dsdrv3_(&myRow,&myCol,myvv,mydvalue,myA,myB,myB_inv);

                

               printf("EigenVector:\n");

               for (int i=0;i<mySIZE;i++)

               {

                     for (int j=0;j<2;j++)

                    {

                          printf("%lf\t",myvv[j*mySIZE+i]);

                    }

                    printf("\n");

               }

               

               getchar();

               return 0;

          }

 Ok, Rebult...

        ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

 Cheers again! That's cool !

   

 The A matrix I used is surely symmetric, the B matrix is surely positive-definite and symmetric. So the argument for the dsdrv3 is right!

 Then Let's check the result:


 Aha, I choosed to output 2 eigenvalue and 2 eigenvectors, compared with the matlab or you can compute it with your own hands, you will say "The result is right!".

 

 Ok, I've finished this article!

 

  I hope it will help other friends to hold ARPACK in Visual studio platform with your C/C++ projects.

 

 If you have any suggestions & questions, or find some errors, please send me a E-mail.

 

 Finally, thanks to the MinGW64/MSYS/ARPACK project group and other relative web-blog authors!

 

                                                                         Zeng qiang

                                                                          2013-3-4

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值