Fixing TOKUDF errors (“Symbol already uniquely defined”)

With Synergy/DE 10.3.3, we updated dblproto so that it now creates a single prototype file (.dbp) containing prototypes for all subroutines, functions, and classes rather than a file for each routine/class. Although this greatly simplifies prototyping, improves prototyping performance, and results in better IntelliSense support, it can break code, highlight errors with imports, and cause TOKUDF errors for duplicate prototyped routines and duplicate global structures. (See the tr#36331 entries in the 10.3.3 Synergy DBL release notes, REL_DBL.TXT, for more information on this change.)

Basically, a TOKUDF error indicates that multiple routines or structures have the same name. Generally, this occurs with a multi-file compile or when prototyping multiple source files together. When a routine or structure in one file has the same name as a routine or structure in another file, you’ll get a TOKUDF error: “Symbol already uniquely defined.” (If two prototype files have symbols with the same name, the error text is “Symbol already uniquely defined in external prototype.”)

Duplicate routines

We often see TOKUDF errors when a Synergy program with the following basic structure is prototyped and compiled in a single unit when previously files were prototyped/compiled separately. (For example, this can happen when a project is moved into Visual Studio, where all source files are built together.)

    Mainlines -->      Program1       Program2

                           \            /

    ELBs -->                AP        AR

                              \      /

    Shared core ELBs -->        CORE

In this situation, the ELBs (AP and AR in this example) often contain routines with the same name and signature. For example, both AP and AR could have an ERROR routine that takes two arguments, but with different implementations. The best-practice solution for this is simply to rename the routines—e.g., AP_ERROR and AR_ERROR. You then need to update every call to these routines. This may sound daunting, but with careful use of Visual Studio’s Search and Replace feature, it can be quite manageable.

If you want to limit changes to only a few files, however, there is an alternative:

  1. Create a dummy routine with the same name and signature (but no logic) in a core-level library. For a Visual Studio project, make it a proto-only file. (See “Creating a prototype-only reference” for more information.) If you’re not using Visual Studio, add this file to your dblproto input file list, but not to the compile.
subroutine error
    arg1,   a        ;etc.
proc
    ;No logic here. This code will never be compiled, just prototyped
endsubroutine
end
  1. Set the routines in the higher-level ELBs to “noproto”—in other words, add the .NOPROTO compiler directive before the routine and .PROTO after it (to end the noproto block).
.noproto
subroutine error
    arg1,   a        ;etc.
proc
   <code to handle errors>
endsubroutine
.proto
end

Then, when the solution is built, dblproto will prototype the dummy version in the core library, while the compiler will compile the routines in the other ELBs. (Both dblproto and the compiler are run automatically under the hood during a Visual Studio build for traditional Synergy.) This will eliminate the TOKUDF errors for those routines, and because there’s a prototype, the compiler will ensure that calls to the routines have the right number and type of arguments, and you’ll get IntelliSense in Visual Studio.

Duplicate enumerations or structure definitions

If the TOKUDF errors are caused by duplicate enumerations or structure definitions (common with xfServerPlus), set the allowdup compiler option on the Compile Page of Project Designer. Or, if you’re not using Visual Studio, use the ‑qrelax:allowdup compiler option for multi-file compilations.