Compiling Fortran netCDF programs on Ubuntu - fortran

Ok, newb question here.
I'm trying to compile simple_xy_wr.f90 -- a netCDF example program -- using gfortran on Ubuntu, and I must be doing something pretty silly; I don't have much experince compiling Fortran.
First, I've got the libnetcdf-dev package installed, which includes files like
/usr/lib/libnetcdf.a
/usr/lib/libnetcdff.a
/usr/include/netcdf.mod
So, I've tried to compile the code with (various command like)
f95 -o xy -I/usr/include/ -L/usr/lib/ -lnetcdff -lnetcdf simple_xy_wr.f90
and I get the following output
/tmp/ccE6g7sr.o: In function `check.1847':
simple_xy_wr.f90:(.text+0x72): undefined reference to `__netcdf_MOD_nf90_strerror'
/tmp/ccE6g7sr.o: In function `MAIN__':
simple_xy_wr.f90:(.text+0x284): undefined reference to `__netcdf_MOD_nf90_create'
simple_xy_wr.f90:(.text+0x2b6): undefined reference to `__netcdf_MOD_nf90_def_dim'
simple_xy_wr.f90:(.text+0x2e8): undefined reference to `__netcdf_MOD_nf90_def_dim'
simple_xy_wr.f90:(.text+0x432): undefined reference to `__netcdf_MOD_nf90_def_var_manydims'
simple_xy_wr.f90:(.text+0x468): undefined reference to `__netcdf_MOD_nf90_enddef'
simple_xy_wr.f90:(.text+0x4aa): undefined reference to `__netcdf_MOD_nf90_put_var_2d_fourbyteint'
simple_xy_wr.f90:(.text+0x4cb): undefined reference to `__netcdf_MOD_nf90_close'
collect2: error: ld returned 1 exit status
I think that I'm including the right libraries. E.g. it seems that __netcdf_MOD_nf90_strerror should be there:
$ nm /usr/lib/libnetcdff.a | grep __netcdf_MOD_nf90_strerror
000000000004a100 T __netcdf_MOD_nf90_strerror
What am I doing wrong?
(FWIW, a few relevant references I've looked at are below.
undefined reference using netcdf library
Compiling problems with gfortran and NETCDF
Compiling and Running Fortran Programs - a basic guide
)

Ordering of object files and archives on the linker command line is very important on Unix systems since the default linker behaviour is to search for symbol definitions only in archives that follow the object file or archive, where an unresolved reference was found, referred to single pass linking.
This means that if your code references __netcdf_MOD_nf90_strerror, then the archive that contains the definition of this symbol (libnetcdff.a) must appear after the list of object files from your program. libnetcdff.a itself references symbols from the C library libnetcdf.a, hence it must be linked after libnetcdff.a. So the correct link order is:
/tmp/ccE6g7sr.o libnetcdff.a libnetcdf.a
where /tmp/ccE6g7sr.o is the temporary object file that the assembler produces from the compiled source file. The correct command line to compile your code is then:
f95 -o xy -I/usr/include/ simple_xy_wr.f90 -lnetcdff -lnetcdf
In this case the linker is not called directly, rather the compiler does it. GCC compilers pass all link-related things in the same order to an intermediate utility called collect2 which then calls the actual linker ld.
Note that if shared object versions of the netCDF library archives are also present (i.e. there are libnetcdff.so and libnetcdf.so), then the linker would prefer them to the static archives (unless static linking is enabled with the -static option) and the final link phase would be handled to the run-time link editor (RTLD) (/lib64/ld-linux-x86-64.so.2 on Ubuntu). In this case the same command line as in your question would actually succeed without link errors, despite the fact that both libraries are positioned before the code that references them, as the missing symbol references would be resolved by the RTLD while it is loading the executable file.

In Ubuntu 12.10, the order of the libraries is the trick (as Hristo suggested):
angelv#palas:~$ gfortran -o xy -I/usr/include/ -L/usr/lib/ -lnetcdf -lnetcdff simple_xy_wr.f90
/tmp/ccj95anF.o: In function `check.1847':
simple_xy_wr.f90:(.text+0x72): undefined reference to `__netcdf_MOD_nf90_strerror'
/tmp/ccj95anF.o: In function `MAIN__':
simple_xy_wr.f90:(.text+0x284): undefined reference to `__netcdf_MOD_nf90_create'
simple_xy_wr.f90:(.text+0x2b6): undefined reference to `__netcdf_MOD_nf90_def_dim'
simple_xy_wr.f90:(.text+0x2e8): undefined reference to `__netcdf_MOD_nf90_def_dim'
simple_xy_wr.f90:(.text+0x432): undefined reference to `__netcdf_MOD_nf90_def_var_manydims'
simple_xy_wr.f90:(.text+0x468): undefined reference to `__netcdf_MOD_nf90_enddef'
simple_xy_wr.f90:(.text+0x4aa): undefined reference to `__netcdf_MOD_nf90_put_var_2d_fourbyteint'
simple_xy_wr.f90:(.text+0x4cb): undefined reference to `__netcdf_MOD_nf90_close'
collect2: error: ld returned 1 exit status
angelv#palas:~$ gfortran -o xy -I/usr/include/ simple_xy_wr.f90 -L/usr/lib/ -lnetcdf -lnetcdff
angelv#palas:~$ ./xy
0 12 24 36
*** SUCCESS writing example file simple_xy.nc!

Related

Compiling using gcc of a Cpp code which is calling a TCL script

I have a cpp code in which I have included tcl.h library. I am trying to compile it using the gcc compiler. but I'm getting the following error :
gcc -o top.o -std=c99 top.c
top.c:12: warning: return type defaults to 'int'
/tmp/ccDOTTZQ.o: In function `main':
top.c:(.text+0xa): undefined reference to `Tcl_CreateInterp'
top.c:(.text+0x1f): undefined reference to `Tcl_EvalFile'
top.c:(.text+0x3d): undefined reference to `Tcl_GetVar2Ex'
top.c:(.text+0x75): undefined reference to `Tcl_ListObjGetElements'
top.c:(.text+0xb1): undefined reference to `Tcl_GetString'
top.c:(.text+0xcc): undefined reference to `Tcl_GetInt'
collect2: ld returned 1 exit status
Its not able to find the Cpp-tcl APIs. Kindly help me with this.
Your code is not linking to the Tcl library, so obviously it can't find the implementations of those functions. (In C and C++, the linking to the implementations of functions is a separate stage from the use of the declarations of those functions, which is what the header files provide.)
Except that you're actually calling gcc wrong. You need to use two steps, first with -c to compile the source code to an object file:
gcc -c -o top.o -std=c99 top.c
Then like this to link the result and make an executable:
gcc -o top.exe -std=c99 top.o -ltcl
With the first, you might need to additionally specify an appropriate -I option to locate the include files (if they're not in the standard locations). With the second, you might need to specify an appropriate -L option to locate the library files (libtcl.so). Depending on the system, you might also need to specify some version numbers (e.g., -ltcl86 or -ltcl8.6 instead of -ltcl). These are all options that depend on your build system configuration, so they're hard to predict exactly here.

TCL - undefined reference to `_imp__Tcl_ResetResult' for g++

I am relatively new to TCL and I am trying to execute a C++ program using SWIG on Windows 10. Using command prompt. I am not using Visual Studio
I am basically trying to run r_cpp using C++ MinGW from TCL
C:\swigwin-3.0.12\Examples\r\class>swig -c++ -tcl example.i`
C:\swigwin-3.0.12\Examples\r\class>g++ -c example.cxx
C:\swigwin-3.0.12\Examples\r\class>g++ -c example_wrap.cxx -I/Tcl/include/tcl8.6
C:\swigwin-3.0.12\Examples\r\class>g++ -shared example.o example_wrap.o -o example.dll
example_wrap.o:example_wrap.cxx:(.text+0x981): undefined reference to `_imp__Tcl_ResetResult'`example_wrap.o:example_wrap.cxx:(.text+0x995): undefined reference to `_imp__Tcl_SetObjResult'`example_wrap.o:example_wrap.cxx:(.text+0x9b9): undefined reference to `_imp__Tcl_SetErrorCode'
example_wrap.o:example_wrap.cxx:(.text+0x9cf): undefined reference to `_imp__Tcl_ResetResult'
example_wrap.o:example_wrap.cxx:(.text+0x9f3): undefined reference to `_imp__Tcl_SetErrorCode
example_wrap.o:example_wrap.cxx:(.text+0xa1e): undefined reference to `_imp__Tcl_AppendResult'
example_wrap.o:example_wrap.cxx:(.text+0xa3c): undefined reference to `_imp__Tcl_NewStringObj'
collect2.exe: error: ld returned 1 exit status
Can someone please help me on this??
Should I make changes to my Makefile.in in the folder?????
Its been a while since I've done C but I would think that you are not linking in the static/shared library that has the functions that g++ is complaining about. In this case the tcl library something like libTclXX.dll. I'm not too familiar with command lines on windows but something like -llibtclXX.dll -L path_to_tcllib could be added. If I recall correctly tcl does provide a stub library for you to link staticially your extension then at runtime the shared library can be use to resolve the functions... so something like -llibtclstubs.dll . look in your installed lib directory for actual names of these libraries.

FFMPEG: undefined reference to `avcodec_register_all' does not link

So I have a very sample code for trying to decode a FFMPEG video stream.
My problem is avcodec does not want to link, to do so I made a clean installation of Ubuntu 13.04. I have build ffmpeg from source following the guide here: https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
I just want to compile my file. Note that my ubuntu does not have any implementations or header files for avcodec. The command line I use is:
gcc -I/home/USER/ffmpeg_build/include -L/home/USER/ffmpeg_build/lib -lavcodec -o test.exe Downloads/auv/src/dronerosvideo/src/ar2.cpp
/tmp/ccKTprFq.o: In function `fetch_and_decode(int, int, bool)':
ar2.cpp:(.text+0x36e):
undefined reference to `avcodec_register_all'
ar2.cpp:(.text+0x378):
undefined reference to `av_log_set_level'
ar2.cpp:(.text+0x382):
undefined reference to `avcodec_find_decoder'
ar2.cpp:(.text+0x3b1):
undefined reference to `avcodec_alloc_context3'
ar2.cpp:(.text+0x3d6):
undefined reference to `avcodec_open2'
ar2.cpp:(.text+0x46d):
undefined reference to `av_init_packet'
ar2.cpp:(.text+0x50a):
undefined reference to `avcodec_decode_video2'
ar2.cpp:(.text+0x534):
undefined reference to `av_free_packet'
/tmp/ccKTprFq.o:(.eh_frame+0x13): undefined reference to
`__gxx_personality_v0'
collect2: error: ld returned 1 exit status
Just for a sane test if I remove the -L argument compiler says:
/usr/bin/ld: cannot find -lavcodec
Which means that the linker finds the library in /home/USER/ffmpeg_build/lib. Also if we check the library for implementation it exists:
nm ffmpeg_build/lib/libavcodec.a | grep "register_all"
0000000000000000 T avcodec_register_all
Also as advised since it is C++ I have exten "C" around the include of the library.
At this point I'm falling out of any ideas at all, why exactly compilation fails?
First, it is C++, so you'll need to use g++ not gcc so that the C++ standard library gets linked. This should get rid of undefined reference to '__gxx_personality_v0'.
Then, the order of libaries to link is actually important.
You'll need to specify a library after the object (or source or other library) using it.
Putting it together, a command line like this works (in my tests):
g++ -o test.exe -I$HOME/ffmpeg/include test.cc -L$HOME/ffmpeg/lib -lavcodec
(Actually, depending on how ffmpeg was built, you might need other libraries as well, like pthreads or libx264)
If you got pkg-config installed, it might be possible to just ask that it for proper clags:
# Since you didn't install ffmpeg to a known location, tell pkg-config about that location.
export PKG_CONFIG_PATH=$HOME/ffmpeg/lib/pkgconfig
g++ -o test.exe $(pkg-config -clags libavcodec) test.cc $(pkg-config -libs libavcodec)

__imp link errors using g++ running under mingw

I have a simple socket program that I'm trying to compile using g++ running in mingw (both the latest versions) on a Win8 system. I'm getting the common linker errors
undefined reference to `__imp_socket'
undefined reference to `__imp_gethostbyname'
I've tried adding -lws2_32 with no luck; i.e. it still can't find the references. Can someone suggest something else I might be missing?
Here's the full output:
G:\source\kak>g++ -o ./test_client -lws2_32 test_client.C
C:\Users\kenkahn\AppData\Local\Temp\ccDZTr9b.o:test_client.C:(.text+0x4f): undefined reference to `__imp_inet_addr'
C:\Users\kenkahn\AppData\Local\Temp\ccDZTr9b.o:test_client.C:(.text+0x6b): undefined reference to `__imp_socket'
C:\Users\kenkahn\AppData\Local\Temp\ccDZTr9b.o:test_client.C:(.text+0x8b): undefined reference to `__imp_connect'
d:/program files/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\kenkahn\AppData\Local\Temp\ccDZTr9b.o: bad reloc address 0xc in section `.xdata'
collect2.exe: error: ld returned 1 exit status
Try putting the -lws2_32 after the test_client.C parameter. The linker of gcc (ld) is touchy about the order of linkable things, this is probably why it doesn't find your imported functions at link time.

undefined references in libpthread and libc

I'm having trouble compiling some examples in a odbc sdk. After some time mingling with the library order, I somehow managed to get the number of undefined references to just a handful of them.
Sadly, I can't figure out how to get rid of the remaining ones. Here's the command that's failing:
g++ -Wall -z defs -m64 -DSIMBA -D_REENTRANT -fPIC -O0 -g -shared Common/TabbedUnicodeFileReader_Linux_x8664_debug.cpp.o Core/QSConnection_Linux_x8664_debug.cpp.o Core/QSDriver_Linux_x8664_debug.cpp.o Core/QSEnvironment_Linux_x8664_debug.cpp.o Core/QSStatement_Linux_x8664_debug.cpp.o DataEngine/QSDataEngine_Linux_x8664_debug.cpp.o DataEngine/QSMetadataHelper_Linux_x8664_debug.cpp.o DataEngine/QSTable_Linux_x8664_debug.cpp.o DataEngine/QSTableUtilities_Linux_x8664_debug.cpp.o DataEngine/QSTypeInfoMetadataSource_Linux_x8664_debug.cpp.o Common/QSTableMetadataFile_Unix_Linux_x8664_debug.cpp.o Common/QSUtilities_Unix_Linux_x8664_debug.cpp.o Main_Unix_Linux_x8664_debug.cpp.o -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--whole-archive,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libSimbaDSI_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libSimbaSupport_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libAEProcessor_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libCore_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libDSIExt_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libExecutor_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libParser_debug.a,/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//Lib/Linux_x8664/libSimbaODBC_debug.a -Wl,--no-whole-archive -Wl,--soname=../Bin/Linux_x8664/libQuickstart_debug.so -L/home/hector/Downloads/SimbaEngineSDK/9.0/DataAccessComponents//ThirdParty/icu/Linux_x8664/lib -licuuc_simba64 -licudata_simba64 -licui18n_simba64 -lpthread -lm -lc -ldl -Wl,--version-script=exports_Linux.map -o ../Bin/Linux_x8664/libQuickstart_debug.so
Edit: Missing symbols
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libdl.so: undefined reference to `_dl_rtld_di_serinfo#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_allocate_tls_init#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `__libc_stack_end#GLIBC_2.2.5'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_get_tls_static_info#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `__tls_get_addr#GLIBC_2.3'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_deallocate_tls#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_rtld_global#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `_dl_argv#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `__libc_enable_secure#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_allocate_tls#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_rtld_global_ro#GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libpthread.so.0: undefined reference to `_dl_make_stack_executable#GLIBC_PRIVATE'
Fixed:
Removing -Wl,--no-allow-shlib-undefined seemed to do the trick. The built shared library seems to work perfectly.
I had a similar issue with a completely separate application. The following compile time flag worked for me:
-B/usr/lib/gold-ld/
which i found at:
https://bugs.launchpad.net/ubuntu/+source/binutils/+bug/885927
I'm using gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 I was trying to compile with lto.
You do a very common newbie mistake. you place the libraries to link with in the middle or the beginning of the command line. The linker GCC uses needs dependencies in reverse order. That means if you have an source/object file S using a function in library L, the file A has to be before the library L on the command line.
In short, put the libraries (-lm -lc -ldl) last on the command line instead.
If linker fails to resolve all referenced symbols then this can be a result of wrong order of provided libraries. If you are not sure what is the correct order then put archives in "--start-group archives --end-group" which according to ld manual will force linker to search the specified archives repeatedly until no new undefined references are created. But pay attention to a performance cost.
The OP mentioned "Removing -Wl,--no-allow-shlib-undefined" helped.
In my case I had to add the opposite:
-Wl,--allow-shlib-undefined
(Everything was working fine with an older version of GCC)