How to use static library that contains C++20 modules

Viewed 837

I have a static library project UserInterface that contains the following module:

// Foo.ixx
export module Foo;

export void MyFunc();

void MyFunc()
{
    []() {};
}

The module Foo is imported in the main header of the library like this:

// NuiLibrary.hpp
#pragma once

import Foo;

// Windows
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

// other includes

I cannot build the solution, I can build the static library but in my Sculpt project that references the library I get these errors: enter image description here

After much search I think it's because modules need to be included explicitly in the client solution by setting Additional Module Dependencies. enter image description here

What's the syntax for it ? Why doesn't it just work despite setting this: enter image description here

2 Answers

What was the cause ?

After a day of trying my specific problem was that the Microsoft Package Server was file locking the .ifc file causing the could not find module error.

How to detect ?

You can find out if you have this issue by trying to compile the module just by itself via right click module -> Compile. It will then fail to compile the file with the error could not open the file another process is using it.

The (non)solution

In a fit of rage I just set everything to default in my static library project setting and now it just works.

What can definitely cause this

When you configure your solution you must do the following:

  • in the client project add a reference to the static library project (this will remove the error from the client project) enter image description here
  • in the static library go Project Settings->C/C++->General and tick the Scan sources for module dependencies (this will remove the error from the library project) enter image description here

Other Issues

In the older versions of Visual Studio 2019 when you renamed a file from .hpp to .ixx the compiler would still recognize the file as a header file. To fix this go to the file properties and set the Item type to C/C++ compiler instead of C/C++ header.

In the current version of Visual Studio 2019 when you create a module file you need to go to file properties C/C++->Precompiled headers->Precompiled Header and click Not using precompiled header. This will fix the following nasty error: enter image description here

Without having any experience with modules in Visual Studio, I can still see some strange stuff.

Header files should not be used together with modules as we see with your NuLibrary.hpp file. While the syntax looks okay you get problems if that header is included inside the global module fragment (GMF) of other source files that declare modules because import declarations may not appear inside GMF:

// some source file including your header
module;

#include "NuLibrary.hpp" // --> ERROR! import declaration..

What I would recommend is to completely forget the idea of having a "main header" of a module project and instead place all that functionality in a module interface file for your project:

// NuLibrary.cpp
module;

// Windows
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

// other includes

export module nulibrary;
import Foo;

[...]

I suppose Visual Studio would prefer if you have that file the .ixx-extension..

Related