I have a simple fortran code test.f90 as following:
For me, compilation works also with the -static flag, and the program gives the same output as without. When you do the dynamic linking, then this resolves to the following symbols:
$ ldd stat.dyn linux-vdso.so.1 => (0x00007fff63fc4000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4826daf000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4826b92000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f48267c8000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f48265b1000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f48263ad000) /lib64/ld-linux-x86-64.so.2 (0x00007f48270b8000)
So, for the static linking, it wants to add libm, libc, and libdl which is doesn't find. Probably it looks for them in the wrong places. Did you transfer the ifort installation somehow, or maybe you are lacking some of the static versions of those libraries.
Hi, Juergen R.,
Thank you for your comment. On our Linux machine, I can find libm, libc, and libdl located at /usr/lib:
lrwxrwxrwx. 1 root root 19 Dec 13 17:16 /usr/lib/libm.so -> ../../lib/libm.so.6
lrwxrwxrwx. 1 root root 12 Dec 13 17:16 /usr/lib/libm.so.6 -> libm-2.17.so
-rw-r--r--. 1 root root 238 Nov 23 01:35 /usr/lib/libc.so
lrwxrwxrwx. 1 root root 12 Dec 13 17:16 /usr/lib/libc.so.6 -> libc-2.17.so
lrwxrwxrwx. 1 root root 20 Dec 13 17:16 /usr/lib/libdl.so -> ../../lib/libdl.so.2
lrwxrwxrwx. 1 root root 13 Dec 13 17:16 /usr/lib/libdl.so.2 -> libdl-2.17.so
But when I use ifort with option -static to compile the code, it shows the errors:
ld: cannot find -lm
ld: cannot find -lc
ld: cannot find -ldl
Our Linux system is administrated by our IT department and I don't know how they installed the Ifort package. If you can advice the steps how to install the IFORT package, I can forward your email to our IT department.
Those libraries are installed as part of your linux. Most current linux distros install only the shared libraries, which you have looked for. You already told us the program runs when you allow ifort to link the shared libraries. If the static libraries were installed, you would expect to find them in the same directory as the shared libraries, and they should share a name or link with the corresponding shared libraries (with .a suffix in place of .a). The procedure to add static libraries to your linux libraries varies with your brand of linux; in fact, some of the commercial linux versions require a special license for the static libraries, which would make it impractical for your installation. In that case, your workaround would be to try to find a compatible library from an open source equivalent distro, put it in your own file syatem, and try to link against it. There may be a few libraries for which no static is available. Definitely not something you could expect anyone to help with. ifort uses the standard linux machinery (ld) to decide whether to use static or shared libraries.
Your comments are very helpful. I want to provide you more information so you might be able to tell us whether the static libraries were not installed on our Linux. For the command 'ifort test.f90", it generates the executable file a.out. The command "ldd a.out" shows the following message:
linux-vdso.so.1 => (0x00007ffdeb9c9000)
libm.so.6 => /lib64/libm.so.6 (0x00002b744575a000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b7445a5d000)
libc.so.6 => /lib64/libc.so.6 (0x00002b7445c79000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b744603c000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b7446253000)
The same as Juergen provided above with option -static compilation. I try to find the file 'libm.a' at /usr/lib or /lib64, but I cannot find it in both of them (I did find the file 'libmcheck.a'. Therefore, it seems the static libraries were not installed on our Linux, am I right?
Our Linux machine OS is Red Hat Enterprise Linux 7.4. Can you provide the advice to install the static libraries so I can forward your advice to our IT person to install it?
we have systems with Redhat CentOS 7.4 which should be very similar. There I get this one, when I check on the (existing) file libm.a:
$ yum whatprovides /usr/lib64/libm.a
Loaded plugins: fastestmirror, langpacks, priorities, protectbase
Determining fastest mirrors
glibc-static-2.17-196.el7.x86_64 : C library static libraries for -static
Repo : base
Filename : /usr/lib64/libm.a
Sp, ask the IT to install the corresponding version of the glibc-static package.
Thank you very much. I have forwarded your advice to our IT asking them to install the glibc-static package. I will update the result when this package is installed.
Hi, Juergen and Tim,
This is update for the issue I submitted. After our IT installed the glibc-static package, I can compile the simple code with option -static to generate a 'not a dynamic executable' file. After run the executable files generated from without and with option -static, the identical results are obtained. Thank you very much for both of your help.
I have come across another issue. When I compile the Fortran by using NetCDF library without option -static, it goes through well. However, when I compile it with option -static, is shows error such as:
fort-vario.c:(.text+0xb7): undefined reference to `nc_get_var_double'
/usr/local/lib/libnetcdff.a(fort-vario.o): In function `nf_put_var_':
Where libnetcdff.a is the NetCDF library. It seems when the option -static is used, the NetCDF library is not working properly. I remember when we installed the NetCDF package, we didn't choose the static option. Is this the reason to cause the error? Or after the glibc-static package is installed, the NetCDF package needs to be re-installed?
If NetCDF is a default build, its dynamic libraries will need to be on path. Presumably, the normal netCDF environment variable settings should accomplish this.
Also note that there are different libraries, libnetcdff is only the one for the fortran interface of netCDF, the function whose symbol is not found is coming from the underlying base (C) library libnetcdf. Maybe that one is simply missing from your link command?
Hi, Juergen and Tim,
Thank you for your quick response.
I try the following four compilations. The Fortran code is called convert2.f. The NetCDF library is installed at /usr/local/lib. The first compilation is (without option -static):
ifort convert2.f -o convert2 -I/usr/local/include -L/usr/local/lib -lnetcdff
This compilation passes and I can run its generated executable file 'convert2' to get the expected files.
The second compilation is:
ifort -static convert2.f -o convert2 -I/usr/local/include -L/usr/local/lib -lnetcdff
The following error message:
/usr/local/lib/libnetcdff.a(fort-attio.o): In function `nf_put_att_text_':
fort-attio.c:(.text+0x70): undefined reference to `nc_put_att_text'
/usr/local/lib/libnetcdff.a(fort-attio.o): In function `nf_get_att_text_':
fort-attio.c:(.text+0x175): undefined reference to `nc_get_att_text'
/usr/local/lib/libnetcdff.a(fort-attio.o): In function `nf_put_att_int1_':
fort-attio.c:(.text+0x287): undefined reference to `nc_put_att_schar'
/usr/local/lib/libnetcdff.a(fort-attio.o): In function `nf_get_att_int1_':
fort-attio.c:(.text+0x395): undefined reference to `nc_get_att_schar'
/usr/local/lib/libnetcdff.a(fort-attio.o): In function `nf_put_att_int2_':
fort-attio.c:(.text+0x4a7): undefined reference to `nc_put_att_short'
/usr/local/lib/libnetcdff.a(fort-attio.o): In function `nf_get_att_int2_': and more
The third compilation is without NetCDF library for Fortran):
ifort -static convert2.f -o convert2 -I/usr/local/include -L/usr/local/lib -lnetcdf
The error message:
/tmp/ifortp0Ob2M.o: In function `MAIN__':
convert2.f:(.text+0x54e): undefined reference to `nf_open_'
convert2.f:(.text+0x575): undefined reference to `nf_inq_dimid_'
convert2.f:(.text+0x599): undefined reference to `nf_inq_dimlen_'
convert2.f:(.text+0x5ce): undefined reference to `nf_inq_dimid_'
convert2.f:(.text+0x5f2): undefined reference to `nf_inq_dimlen_'
convert2.f:(.text+0x624): undefined reference to `nf_inq_dimid_'
convert2.f:(.text+0x648): undefined reference to `nf_inq_dimlen_'
convert2.f:(.text+0x66a): undefined reference to `nf_close_' and more
The fourth compilation is (including both NetCDF for C and Fortran)
ifort -static convert2.f -o convert2 -I/usr/local/include -L/usr/local/lib lnetcdf -lnetcdff
The error message are the same as those shown in second compilation.
Juergen or Tim, if the NetCDF is installed on your machine, would you mind to compile my code so we can quickly diagnose the issue? If yes, I can attach the source code.
I greatly appreciate both of you for your help.
Hi, Juergen and Tim,
One more update. If I use option static-intel instead of -static, the compilation can go through and generates an executable. When I type "ldd convet2.x", it requires many shared libraries:
linux-vdso.so.1 => (0x00007fffb53bb000)
libm.so.6 => /lib64/libm.so.6 (0x00002b387ca14000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b387cd17000)
libc.so.6 => /lib64/libc.so.6 (0x00002b387cf33000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b387d2f6000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b387d50d000)
[zheng@ofswork ~]$ ldd convert2_standardgrid_vv.x |more
linux-vdso.so.1 => (0x00007ffd4c5c4000)
libnetcdff.so.5 => /usr/local/lib/libnetcdff.so.5 (0x00002afee06d5000)
libm.so.6 => /lib64/libm.so.6 (0x00002afee0b74000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00002afee0e76000)
libc.so.6 => /lib64/libc.so.6 (0x00002afee1092000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002afee1456000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002afee166c000)
libnetcdf.so.7 => /usr/local/lib/libnetcdf.so.7 (0x00002afee1870000)
libifport.so.5 => /opt/Intel/compilers_and_libraries_2017.1.132/linux/compiler/lib/intel64_lin/libifport.so.5 (0x00002afee
libifcoremt.so.5 => /opt/Intel/compilers_and_libraries_2017.1.132/linux/compiler/lib/intel64_lin/libifcoremt.so.5 (0x00002
libimf.so => /opt/Intel/compilers_and_libraries_2017.1.132/linux/compiler/lib/intel64_lin/libimf.so (0x00002afee21c0000)
libsvml.so => /opt/Intel/compilers_and_libraries_2017.1.132/linux/compiler/lib/intel64_lin/libsvml.so (0x00002afee26ad000)
libintlc.so.5 => /opt/Intel/compilers_and_libraries_2017.1.132/linux/compiler/lib/intel64_lin/libintlc.so.5 (0x00002afee35
libhdf5_hl.so.8 => /lib64/libhdf5_hl.so.8 (0x00002afee3823000)
libhdf5.so.8 => /lib64/libhdf5.so.8 (0x00002afee3a57000)
libz.so.1 => /usr/local/lib/libz.so.1 (0x00002afee404e000)
libcurl.so.4 => /lib64/libcurl.so.4 (0x00002afee427b000)
libirng.so => /opt/Intel/compilers_and_libraries_2017.1.132/linux/compiler/lib/intel64_lin/libirng.so (0x00002afee44e4000)
libsz.so.2 => /lib64/libsz.so.2 (0x00002afee485a000)
libidn.so.11 => /lib64/libidn.so.11 (0x00002afee4a5d000)
libssh2.so.1 => /lib64/libssh2.so.1 (0x00002afee4c90000)
libssl3.so => /lib64/libssl3.so (0x00002afee4ebb000)
libsmime3.so => /lib64/libsmime3.so (0x00002afee5107000)
libnss3.so => /lib64/libnss3.so (0x00002afee532e000)
libnssutil3.so => /lib64/libnssutil3.so (0x00002afee5659000)
libplds4.so => /lib64/libplds4.so (0x00002afee5886000)
libplc4.so => /lib64/libplc4.so (0x00002afee5a8a000)
libnspr4.so => /lib64/libnspr4.so (0x00002afee5c90000)
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00002afee5ece000)
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00002afee611b000)
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00002afee6404000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00002afee6637000)
liblber-2.4.so.2 => /lib64/liblber-2.4.so.2 (0x00002afee683b000)
libldap-2.4.so.2 => /lib64/libldap-2.4.so.2 (0x00002afee6a4b000)
libaec.so.0 => /lib64/libaec.so.0 (0x00002afee6c9f000)
libssl.so.10 => /lib64/libssl.so.10 (0x00002afee6ea8000)
libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00002afee711a000)
librt.so.1 => /lib64/librt.so.1 (0x00002afee757c000)
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00002afee7784000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00002afee7992000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00002afee7b97000)
libsasl2.so.3 => /lib64/libsasl2.so.3 (0x00002afee7db1000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00002afee7fcf000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00002afee81f6000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00002afee842d000)
libfreebl3.so => /lib64/libfreebl3.so (0x00002afee8690000)
So what is the difference for the option -static and -static-intel?
Based on your comment, if I want to run the executable file on the machine which does not install NetCDF library, I need to use option -static, rather than static-intel, to compile the code on the machine which has NetCDF library. Am I right?
We use default option to install NetCDF 4.4.4. The generated NetCDF library is shared or static? As stated in my previous comment, the compilation without option -static is good, but with option -static, it shows error related to NetCDF library. Does this mean that in NetCDF library installed on our machine is shared library? If yes, how can we install NetCDF static library?
Your help is greatly appreciated.
I never used NetCDF. You should need intel-static only if you want to use it on a computer where no Intel libraries are installed, I guess (statically include Intel libraries). When you don't have NetCDF, then you need -static.
Maybe I need to make my question more clear. In the government department, some computers are allowed to only install the OS, neither Intel compiler nor NetCDF libraries. I want to run executable on this computer (called computer 1). I need to use another computer (called computer 2), which installs Intel and NetCDF libraries, to compile the code to generate this executable.
On computer 2, if I use compilation option -static, it fails. If I use compilation option -static-intel or without this option, to run the executable file, it needs to loading the NetCDF library so the executable file can not be run on computer 1.
Based on your last comment, you suggested to use the option -static-intel to compile the code, but it cannot be run on computer 1. Any suggestion?
Thank you very much for your patience to help us.
Instead of the command line
ifort -static convert2.f -o convert2 -I/usr/local/include -L/usr/local/lib -lnetcdf -lnetcdff
reverse the last 2 libraries so that it is
ifort -static convert2.f -o convert2 -I/usr/local/include -L/usr/local/lib lnetcdf -lnetcdff -lnetcdf
The order in which you specify the libraries is important, at least in a unix like system.