3

I'm learning the C++20 modules feature, but whenever I try to include a header file inside a module and then try to link it, I get a link error. I got the error when working with the GLFW library, but I made a minimum reproducible example so you can help me more easily.

Here are the steps to reproduce this issue:

  1. Get a .a file with a function definition:
// lib.h
void libraryFunction();
// lib.cpp
#include "lib.h"

void libraryFunction() {}
clang++ -c -o lib.o lib.cpp
ar rc lib.a lib.o
  1. Now that you have the lib.a file, write and compile a module that uses it:
// test.cpp
export module test;
#include "lib.h"

export void testFunction() {
    libraryFunction();
}
clang++ -std=c++20 -c -fmodules-ts -Xclang -emit-module-interface -o test.pcm test.cpp
  1. Write a main.cpp file and try to compile and link it:
clang++ -std=c++20 -fmodules-ts -fprebuilt-module-path=. -o main main.cpp test.cpp -l:lib.a -L.
  1. You should get this error:
/usr/bin/ld: /tmp/test-25d7c8.o: in function `testFunction()':
test.cpp:(.text+0x5): undefined reference to `_ZW4testE15libraryFunctionv'
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)

How do I fix this? I don't get the error when I #include "lib.h" and call libraryFunction() in main.cpp, but what I want is to call the library API from a module. Is this possible?

Volper
  • 644
  • 6
  • 14
  • Does this answer your question? [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White Apr 26 '21 at 12:41

1 Answers1

2

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.

luk32
  • 15,812
  • 38
  • 62
  • You need `module;` as the very first thing to allow such `#include`s, although MSVC probably doesn’t enforce that (yet) since their implementation predates that rule. – Davis Herring Apr 26 '21 at 15:29
  • @DavisHerring I tested this on clang10 with std2a. If you could point me to a source I'd be glad to correct. I won't pretend I am an expert on modules and resources are pretty scarce yet. I read [clang doc's on modules](https://clang.llvm.org/docs/Modules.html#includes-as-imports) and didn't see the requirement, but maybe they are (too) friendly too. – luk32 Apr 27 '21 at 08:14
  • I have only [the standard](https://timsong-cpp.github.io/cppwp/n4861/basic.link#nt:translation-unit): much of what Modules documentation does exist is based on the (divergent) pre-standardization implementation. – Davis Herring Apr 27 '21 at 15:35