I am trying to compile some source code and I am having issues. The code is written in C and FORTRAN and I am running into an issue with my compilers going from one to the other. This is the error message being returned;
mod_par.o: In function `__mod_par_MOD_domdec':
mod_par.f90:(.text+0x35a47): undefined reference to `partition_'
collect2: error: ld returned 1 exit status
make: *** [fvcom] Error 1
This is what I believe to be the offending bit of code from the file mod_par.F;
# if !defined (PARTITION_SPECIAL)
So I have been advised that this is a common problem encountered due to different naming conventions in C and FORTRAN. I have been give some advice on how to go about solving the problem, however, I don't understand the advice. It is as follows;
1) Work out which library hosts this partition function
2) Read through the docs for that library to find out how to generate a fortran wrapper library
3) Make sure you link through to the wrapper library as well as the original library
Anyone able to put this into laymans terms for me/advise on how to proceed/point me on to info to help me proceed? Let me know if you need anymore info.
I actually resolved this the issue was that I was building the application using mpi compilers and the METIS library that was required for a parallel build was not linked. I linked this and the application is now built. – deiniol
Related
We are porting an application from HPUX to Linux using Microfocus COBOL and GNU C on both platforms.One of our shared libraries is failing at runtime with the following error:
AB123: symbol lookup error. libRTS.so: undefined symbol: _mFldhandle
My understanding is that _mFldhandle is internal to Microfocus.
Can anyone point me to why we might be having an issue / what we should be including to make sure _mFldhandle is available at runtime?
Thanks!
Contrary to the comments from above the usual reason for this symbol being missing is not using "cob" to link your exe or shared object.
The other reason is not using the same 'C' compiler that the product was created with.
I'm trying to call the STM32 Cube Programmer C libraries from Rust.
The entire code, and branches showing various attempts, are available here:
https://github.com/becky112358/rust_c_linking_stm32_cube_programmer
Attempt 1 (in my GitHub repository, branch main)
Following the Rust Bindgen tutorial: https://rust-lang.github.io/rust-bindgen/
This is my preferred method. A Rust crate wraps the C library. Other Rust crates can then include the Rust wrapper crate, and not have to worry about any C libraries.
... in theory.
The Rust crate wrapping the C library (libstm32_cube_programmer_sys) builds ok. Its tests run ok.
The Rust crate calling the Rust crate which wraps the C library (caller) does not build, but reports:
= note: LINK : fatal error LNK1181: cannot open input file '.\drivers\CubeProgrammer_API.lib'
Why is caller even trying to look for the C library? I expected libstm32_cube_programmer_sys to handle all C library to Rust conversion, and that any Rust crates then calling libstm32_cube_programmer_sys could be purely Rusty (with maybe some unsafeness).
In build.rs I initially mis-wrote the C library name, and libstm32_cube_programmer_sys did not build. Correcting the library name allowed libstm32_cube_programmer_sys to build successfully. So it seems like libstm32_cube_programmer_sys does open the C library.
I tried adding the path to the drivers folder to my PATH.
I tried listing the absolute path to the C library:
println!("cargo:rustc-link-lib=C:/[blah blah]/drivers/CubeProgrammer_API");
I could not find how to feed in the path correctly, without Rust reporting:
error: renaming of the library `C` was specified, however this crate contains no `#[link(...)]` attributes referencing this library.
Attempt 2 (branch all_in_one)
In the main branch it seemed like maybe the problem was that libstm32_cube_programmer_sys could find the C library but caller could not. So I tried discarding the separate Rust crate, and having a single Rust crate which both wraps the C library and calls the C functions.
This time I get the following error, plus a bonus warning:
= note: caller.59pofysds2mkvvjr.rcgu.o : error LNK2019: unresolved external symbol disconnect referenced in function _ZN6caller4main17ha79648c0a9e86ed0E
.\drivers\CubeProgrammer_API.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'
Attempt 3 (branch link_search)
I searched a lot on the internet and found lots of different ways to call a C library from Rust. One way is to use link-search rather than link-lib. This surely only makes things harder for the compiler because you make it do more work. But I am stuck and need to try different things!
This time I get the following error, plus the bonus warning:
= note: caller.59pofysds2mkvvjr.rcgu.o : error LNK2019: unresolved external symbol __imp_disconnect referenced in function _ZN6caller4main17ha79648c0a9e86ed0E
.\drivers\CubeProgrammer_API.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'
Question
How do I make this work? Ideally from Attempt 1, but I'll take anything!
When we have:
C library <- Rust library <- Rust code
It seems that
when compiling, the Rust code needs to be able to see the C library, even though it is also calling the Rust library
when running, there may be C dlls which you need to store alongside the Rust exe
That was my main misunderstanding when I posted my original question.
Some other tips / reminders:
Make sure to use the correct lib file! (x64, x86 etc)
Resolve warnings too!
Recently I've got interested in learning the heap management of C (the malloc module). I want to break the malloc source files(e.g., malloc.c, arena.c) into smaller files so it's easier to read and study for me. I'm using the glibc 2.23 and have successfully built it locally (in a separate "build" folder) on Ubuntu 14.04 following the instructions on wiki.
As my initial attempt, I put the __malloc_assert into the files massert.h and massert.c but then realized I have no idea how to add them to the makefiles so they can get compiled and linked.
Since I moved __malloc_assert out of malloc.c, I got the link errors when running make again, which was expected:
/home/mvs/git/glibc/build/libc_pic.os: In function `detach_arena':
/home/mvs/git/glibc/malloc/arena.c:629: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/build/libc_pic.os: In function `mremap_chunk':
/home/mvs/git/glibc/malloc/malloc.c:2832: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/malloc/malloc.c:2813: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/malloc/malloc.c:2812: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/malloc/malloc.c:2830: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/build/libc_pic.os:/home/mvs/git/glibc/malloc/malloc.c:2776: more undefined references to `__malloc_assert' follow
I thought I should look at how the malloc/malloc.c is used in the makefiles, but I couldn't find where it is used. I'm mainly looking at the following files:
glibc/Makeconfig
glibc/Makefile
glibc/Rules
glibc/malloc/Makefile
Alternatively, I've searched the makefile on libc-help mailing list and looked at all the results but didn't find one that matches what I want. Two of the threads, "glibc + add new function" and "Adding a function to glibc?", were talking about adding a new function to the library, which is not my case (I'm not adding new function but merely restructuring the code).
I'm kind of new to the makefile system and still reading the GNU makefile manual, but thought shooting an email here may get me out of the struggle more quickly.
Thanks!
You need to add massert (not massert.c) to the routines variable in malloc/Makefile.
There are several such variables: routines is for libc it self, but there is also libm-routines for libm, and so on.
By default, these source files are built for all variants: static (.o), shared (.os), profiling (.op, profiling builds are disabled by default though). Some special functions are only intended for static builds (.oS, they go into libc_nonshared.a) and are listed in static-only-routines as well. Specific build targets can be excluded using the elide-routines.os variable.
I have a pretty special problem. I need to review NASA Parallel Benchmarks for my school project, but I found it to be a very problematic task :-) At first, I tried to work with IS (integer sort), but the code wasn't able to compile, and I found out, that I need to rewrite make.def file. So I rewrote it's variable for mpi.h and compiled it, but the program keeps alerting me:
Fatal error in PMPI_Comm_rank: Invalid communicator, error stack:
PMPI_Comm_rank(108): MPI_Comm_rank(comm=0x0, rank=0x6084e8) failed
PMPI_Comm_rank(66).: Invalid communicator
To be honest, I don't really know, should I do know. I tried even changing the old compilers, like cc to gcc etc. but it doesn't seem to have any effect. Last thing which I tried to rewrite was the variable CMPI_LIB, but I have no idea how to do it correctly.
Thank you very much for all your responses ;-)
And I'm sorry for my bad English, I'm not a native speaker.
The whole benchmark is here for download (cca 600kB): uloz.to/xTSEzTX8/npb3-3-1-zip
File is.c which I'm trying to compile and launch: hostcode.sourceforge.net/view/2436
Makefile: hostcode.sourceforge.net/view/2437
File make.common - takes care of compiling files with special functions etc.: hostcode.sourceforge.net/view/2438
My make.def is here: #veeylg84-46196 - BASH - Sourcecode
Structure of files in my 'benchmark folder': http://www.sourcepod.com/sozaoh48-46200
The PMPI_Comm_rank(108): MPI_Comm_rank(comm=0x0, rank=0x6084e8) failed message tells a lot. Your MPI_COMM_WORLD constant is 0 which is not the case with MPICH-based (as one could guess from the format of the error message) implementations. It is a compile-time constant in MPICH (#define MPI_COMM_WORLD ((MPI_Comm)0x44000000)) and a run-time constant reference in Open MPI. The #1 reason for such errors is mixing MPI implementations, i.e. including mpi.h from one implementation and linking against the libraries of another one.
As evident from your make.def, you are including mpi.h from a dummy MPI implementation and linking against a real MPI library. This simply won't work. Since mpicc takes care of passing the right include paths and library options to the backend compiler, you don't have to set CMPI_LIB or CMPI_INC explicitly and should leave them empty instead. Those are reserved for the case when the MPI implementation does not provide compiler wrappers (mpicc, mpif90, etc.) and one has to explicitly specify all options, which is the case with e.g. MS-MPI.
Any idea about this error?
gcc -oxtmpmain.exe xtmpmain.o fiber_driver.o xtmp_options.o getopt.o D:\usr\xtensa\XtDevToolsDE\in
stall\tools\RB-2008.4-win32\XtensaTools\lib\iss\xtmp.lib
xtmpmain.o(.text+0x213):xtmpmain.c: undefined reference to `_uart_setup'
xtmpmain.o(.text+0x2da):xtmpmain.c: undefined reference to `_uart_cleanup'
collect2: ld returned 1 exit status
make: *** [xtmpmain.exe] Error 1
This is a plain linking error. You're calling two functions, uart_setup() and uart_cleanup(), that the linker is not finding.
There might be several causes, including (but certainly not limited to):
They really are missing, perhaps you forgot to link against one object file
Namespacing preventing the existing function from being found
Library paths
Marshalling or problems with external names and underscores
Without more detail, it's hard to tell for sure.
It means that xtmpmain.c called functions named uart_setup() and uart_cleanup(), but they weren't found by the linker. You probably need to include a library, or to implement those functions for Windows in terms of the Win32 API.
Some "is it plugged in questions" are:
Are the functions declared?
Are the functions defined (i.e. implemented)?
With exactly those names?
Were those definitions excluded by the preprocessor?
There is a gcc option that controls the presence or absence of a leading underscore. You didn't accidentally use that for one file and not others, right?
Verify the declared calling convention. __cdecl and __stdcall are very different animals. They usually produce mismatched exported symbol names for safety, and this error can be a symptom of that.
If this is a porting project, then it is likely that the original implementation of a UART-related function is written in a platform-dependent way. In that case, they often would be guarded by a #ifdef of some form that depends on the compile-time platform.
To resolve that, you would need to implement them for this platform, in a style consistent with their usage in the rest of the application, and similarly guarded.