Linking to Modules Folder Gives Undefined Reference

Linking to modules folder gives undefined reference

You need to include the .o file as well. That is, you should compile this as

gfortran -I/path/to/mods -o test_prog test_prog.f90 mods/test_mod.o

This worked and ran for me.

What is an undefined reference/unresolved external symbol error and how do I fix it?

Compiling a C++ program takes place in several steps, as specified by 2.2 (credits to Keith Thompson for the reference):

The precedence among the syntax rules of translation is specified by the following phases [see footnote].

  1. Physical source file characters are mapped, in an implementation-defined manner, to the basic source character set
    (introducing new-line characters for end-of-line indicators) if
    necessary. [SNIP]
  2. Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to
    form logical source lines. [SNIP]
  3. The source file is decomposed into preprocessing tokens (2.5) and sequences of white-space characters (including comments). [SNIP]
  4. Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed. [SNIP]
  5. Each source character set member in a character literal or a string literal, as well as each escape sequence and universal-character-name
    in a character literal or a non-raw string literal, is converted to
    the corresponding member of the execution character set; [SNIP]
  6. Adjacent string literal tokens are concatenated.
  7. White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. (2.7). The
    resulting tokens are syntactically and semantically analyzed and
    translated as a translation unit. [SNIP]
  8. Translated translation units and instantiation units are combined as follows: [SNIP]
  9. All external entity references are resolved. Library components are linked to satisfy external references to entities not defined in the
    current translation. All such translator output is collected into a
    program image which contains information needed for execution in its
    execution environment.
    (emphasis mine)

[footnote] Implementations must behave as if these separate phases occur, although in practice different phases might be folded together.

The specified errors occur during this last stage of compilation, most commonly referred to as linking. It basically means that you compiled a bunch of implementation files into object files or libraries and now you want to get them to work together.

Say you defined symbol a in a.cpp. Now, b.cpp declared that symbol and used it. Before linking, it simply assumes that that symbol was defined somewhere, but it doesn't yet care where. The linking phase is responsible for finding the symbol and correctly linking it to b.cpp (well, actually to the object or library that uses it).

If you're using Microsoft Visual Studio, you'll see that projects generate .lib files. These contain a table of exported symbols, and a table of imported symbols. The imported symbols are resolved against the libraries you link against, and the exported symbols are provided for the libraries that use that .lib (if any).

Similar mechanisms exist for other compilers/ platforms.

Common error messages are error LNK2001, error LNK1120, error LNK2019 for Microsoft Visual Studio and undefined reference to symbolName for GCC.

The code:

struct X
{
virtual void foo();
};
struct Y : X
{
void foo() {}
};
struct A
{
virtual ~A() = 0;
};
struct B: A
{
virtual ~B(){}
};
extern int x;
void foo();
int main()
{
x = 0;
foo();
Y y;
B b;
}

will generate the following errors with GCC:

/home/AbiSfw/ccvvuHoX.o: In function `main':
prog.cpp:(.text+0x10): undefined reference to `x'
prog.cpp:(.text+0x19): undefined reference to `foo()'
prog.cpp:(.text+0x2d): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o: In function `B::~B()':
prog.cpp:(.text._ZN1BD1Ev[B::~B()]+0xb): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o: In function `B::~B()':
prog.cpp:(.text._ZN1BD0Ev[B::~B()]+0x12): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1Y[typeinfo for Y]+0x8): undefined reference to `typeinfo for X'
/home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1B[typeinfo for B]+0x8): undefined reference to `typeinfo for A'
collect2: ld returned 1 exit status

and similar errors with Microsoft Visual Studio:

1>test2.obj : error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ)
1>test2.obj : error LNK2001: unresolved external symbol "int x" (?x@@3HA)
1>test2.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A@@UAE@XZ)
1>test2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall X::foo(void)" (?foo@X@@UAEXXZ)
1>...\test2.exe : fatal error LNK1120: 4 unresolved externals

Common causes include:

  • Failure to link against appropriate libraries/object files or compile implementation files
  • Declared and undefined variable or function.
  • Common issues with class-type members
  • Template implementations not visible.
  • Symbols were defined in a C program and used in C++ code.
  • Incorrectly importing/exporting methods/classes across modules/dll. (MSVS specific)
  • Circular library dependency
  • undefined reference to `WinMain@16'
  • Interdependent library order
  • Multiple source files of the same name
  • Mistyping or not including the .lib extension when using the #pragma (Microsoft Visual Studio)
  • Problems with template friends
  • Inconsistent UNICODE definitions
  • Missing "extern" in const variable declarations/definitions (C++ only)
  • Visual Studio Code not configured for a multiple file project

Why does g++ detect undefined reference when dynamically linking

With the ELF format it indeed isn't necessary to know which symbols belong to which library, as the actual symbol resolution happens when the program is executed. By convention though ld will still resolve the symbols when producing the binary. It's for your convenience, so that you get immediate feedback when you have missing symbols, since in that case the chance is big your program won't work.

Using the --warn-unresolved-symbols flag you can change ld behavior in this case from an error to a warning:

$ g++ -Wl,--warn-unresolved-symbols main.cpp -lusertest

Should emit a warning but still create the executable. Note that you still need to provide the library name, otherwise ld won't know where to look for the needed symbols.

On Windows, the linker needs to know exactly which symbol belongs to which library in order to produce the necessary import tables. So it is impossible to build a PE binary with unresolved symbols.

How to solve 'undefined reference to'

There may be a problem with the intra-dependencies in SimpleITK with the version Slicer is using
Change:

set(MODULE_TARGET_LIBRARIES
${ITK_LIBRARIES} ${SimpleITK_LIBRARIES}
)

to:

set(MODULE_TARGET_LIBRARIES
${SimpleITK_LIBRARIES} ${SimpleITK_LIBRARIES} ${ITK_LIBRARIES}
)

I believe the follow patch in SimpleITK will addressed the problem:
https://github.com/SimpleITK/SimpleITK/commit/6fc22492ca1fd3ebb493160b7968c37a0a6f1986

undefined reference to function call

The problem is with linking compiled objects.

Try manually compiling your sources like this:

gcc -o convert_driver convert_driver.c conversion.c

In this way, after compilation, the compiler knows what to link.

You can also manually compile sources into objects, and use a static linker to generate the executable:

gcc -c -o convert_driver.o convert_driver.c
gcc -c -o conversion.o conversion.c
ld -o convert_driver convert_driver.o conversion.o

For a typical IDE, check if there's a "Create Project" option. Multi-file support usually comes within the concept of "a project".

Linking error: undefined reference

Your main issue is that you are mixing up Qt 5 with KDE Frameworks 5. That is not going to fly like that. See this yourself:

KDE 4 related linkage: -lkdeui -lkdecore -lkparts
Qt 5 related linkage: -lQt5Widgets -lQt5Gui -lQt5Core

The fix is relatively simple:

LIBS += -lkdecore -lkparts -lKF5Wallet
^^^^^^^^^^^

Naturally, if you move onto KF5, you will also need to change the includepaths to:

INCLUDEPATH += \
...
/usr/include/KF5 \
/usr/include/KF5/KWallet/ \
...

You will need to link against that library should you be using Qt 5 and KF 5. Basically, you were using kde 4, as kdeui is a KDE 4 library. You can check that yourself by issuing the following command:

dpkg -S /usr/lib/libkdeui.so

In short, the WId was unsigned long in the kdeui library since that is what was used for this on X11 platforms, whereas the Qt 5 mix may have confused the quintptr in for the WId, somehow. While Qt 4's WId was different for different platforms, Qt 5's WId is quintptr, so that is clearer.

If you plan to use Qt 4 with KDE 4, your initial code is fine, but you need to make sure that you run Qt 4's qmake in that case as opposed to Qt 5's. This can be either by using qtchooser or running the proper qmake binary directly. qmake --version is always your friend to verify the version that is being run. On my Debian and Archlinux, the corresponding qmake binary is called qmake-qt4.

On a side note, it is strange that you add the widgets module, but you wish to remove the gui, whereas the former depends on the latter. Having seen the widgets module used in the project file, my opinion is even more clear that you probably wish to use the Qt 5 and KF 5 combination at this point in time.

Here is my working Qt 5 and KF 5 test snippet:

main.cpp

#include <QCoreApplication>
#include <KWallet>

using KWallet::Wallet;

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
KWallet::Wallet* wallet = Wallet::openWallet(Wallet::LocalWallet(), 0);
return a.exec();
}

main.pro

TARGET = kwallet-test
TEMPLATE = app
SOURCES += main.cpp
LIBS += -lKF5Wallet
INCLUDEPATH += /usr/include/KF5/KWallet

Build

qmake && make

For this to work on Ubuntu, you will need to install the following package which was added to Utopic (14.10):

sudo apt-get install libkf5wallet-dev

Unfortunately, Trusty Tahr (14.04) did not have this available, but you might be able to backport it if you wish to.

Link error with static library in C++20 module

You've put #include below module, which probably declared libraryFunction as a module function. It makes sense, since linker looks for something like test-libraryFunction.

MS sources on modules (what a time to be alive to use MS as credible source) say you can include "global" headers but it should be done before 1st module declaration.

Try switching the order:

// test.cpp
#include "lib.h"

export module test;

export void testFunction() {
libraryFunction();
}

Should help.



Related Topics



Leave a reply



Submit