Nicholas Kinar
Nicholas Kinar

Reputation: 1470

Open Watcom Linker finding undefined references when linking C and Fortran code to build Matlab mex file

Using Windows 7, Matlab R2011a (32-bit), and Open Watcom Version 1.8, I am attempting to compile a C MEX file that calls Fortran code.

Following directions posted on the Matlab website (support link), I've first compiled a Fortran object file using the following command:

wfl386 -c -fpi87 -SC getqpf.f

I've then attempted to link the object file to a number of C files. All of the C files compile properly, but I receive the following link error. The undefined references are for functions in the C files called from a subroutine in getqpf.f. For example, QESTM is defined as a function in one of the C files as int qestm_().

The q_estimate.c file contains the entry point function for the MEX program. The idea is for the entry point function to call the subroutine in getqpf.f. The subroutine in getqpf.f calls the C code functions in the other files.

How might I get rid of the undefined references?

>> mex q_estimate.c paul2.c paul2_L1.c paul6.c paul6_L1.c runavg.c fit_slope.c getqpf.obj
Open Watcom Linker Version 1.8 
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved. 
Source code is available under the Sybase Open Watcom Public License. 
See http://www.openwatcom.org/ for details. 
loading object files 
searching libraries 
Error! E2028: QESTM is an undefined reference 
Error! E2028: QESTM1 is an undefined reference 
Error! E2028: QESTF is an undefined reference 
Error! E2028: QESTF1 is an undefined reference 
creating a Windows NT dynamic link library 
file getqpf.obj(E:\DEVELOPMENT-FINAL\EXPERIMENTS\test-Q-analysis\getqpf.f): undefined symbol QESTM 
file getqpf.obj(E:\DEVELOPMENT-FINAL\EXPERIMENTS\test-Q-analysis\getqpf.f): undefined symbol QESTM1 
file getqpf.obj(E:\DEVELOPMENT-FINAL\EXPERIMENTS\test-Q-analysis\getqpf.f): undefined symbol QESTF 
file getqpf.obj(E:\DEVELOPMENT-FINAL\EXPERIMENTS\test-Q-analysis\getqpf.f): undefined symbol QESTF1 
  C:\PROGRA~2\MATLAB\R2011A~1\BIN\MEX.PL: Error: Link of 'q_estimate.mexw32' failed. 

Upvotes: 1

Views: 2906

Answers (2)

Hristo Iliev
Hristo Iliev

Reputation: 74435

Just for the sake of completeness: the Open Watcom F77 Programmer's Guide (available here) specifies:

Default symbol naming conventions vary between compilers. Watcom C/C++ prefixes an underscore character to the beginning of variable names and appends an underscore to the end of function names during the compilation process. Watcom FORTRAN 77 converts symbols to upper case. Auxiliary pragmas can be used to resolve this inconsistency.

The document then goes on to explain how one can make the Watcom C/C++ compiler perform the same transformation on external symbols, so that C code can call into Fortran routines, as well as make external to Fortran code symbols be C-like, so that Fortran code can call into C routines. It is not clear if this mechanism can work in reverse, i.e. force a Fortran routine symbol to be exported with specific case.

To achieve this, you have you use a special pragma, which can be used to treat the case that external symbols get:

*$pragma aux cname "!_"

where cname is the name of an external symbol, defined in your C code. The "!_" tells the compiler to use a lowercase version of the name with an added underscore (this presumes that the C files were compiled with Open Watcom C/C++ compiler). If the C compiler does not append underscores, then you should use "!" instead. So, may be, if you add the following to your Fortran code, you won't need to use capitalised names in the C code:

*$pragma aux qestm "!_"
*$pragma aux qestm1 "!_"
*$pragma aux qestf "!_"
*$pragma aux qestf1 "!_"

It is also possible to specify the external name like this:

*$pragma aux qestm "qEsTm_"

or

*$pragma aux qestm "qEsTm"

depending on whether the C compiler adds underscores or not. Then the Fortran code would reference the qestm symbol under the funny name of qEsTm_ (or qEsTm). Of course, you would have to use qEsTm as the name of your C function. The point here is that case is preserved for the name inside the quotation marks.

Upvotes: 1

tomlogic
tomlogic

Reputation: 11694

Since C is case-sensitive with naming, have you tried defining the function as int QESTM_() instead of int qestm_()?

Upvotes: 1

Related Questions