Skip to content

Plane-wave basis header dependencies #8010

Description

@Growl1234

My recent GCC 16 + LTO build on Fedora Rawhide exposed a long-existing deeper dependency issue in the plane-wave basis headers.

Currently, the base-class headers include their derived implementations after the include guard:

// pw_basis.h
#endif // PWBASIS_H
#include "pw_basis_sup.h"
#include "pw_basis_big.h" // temporary it will be removed

and similarly:

// pw_basis_k.h
#endif
#include "./pw_basis_k_big.h" // temporary it will be removed

This effectively reverses the normal dependency direction: including a base class also exposes derived classes and their dependencies.

One visible consequence is MODULE_CHARGE_extra. The test only provides a small mock implementation of PW_Basis, but including the relevant headers also introduces PW_Basis_Sup, PW_Basis_Big, PW_Basis_K, and PW_Basis_K_Big. With GCC 16 + LTO this results in unresolved RTTI/destructor references such as:

undefined reference to `ModulePW::PW_Basis_Sup::~PW_Basis_Sup()'
undefined reference to `ModulePW::PW_Basis_K::~PW_Basis_K()'
undefined reference to `typeinfo for ModulePW::PW_Basis_Sup'
undefined reference to `typeinfo for ModulePW::PW_Basis_K'

The linker failure itself can be worked around by adding more sources/libraries to the unit test, but that would leave the underlying architectural issue unchanged.

Problems

  • Base-class headers implicitly expose derived classes.
  • Translation units acquire dependencies that are not visible from their actual interfaces.
  • Small unit tests and mocks become coupled to much larger parts of the PW implementation.
  • CMake targets can appear to have sufficient dependencies while relying on accidental transitive includes.
  • Changes to the PW class hierarchy can unexpectedly break unrelated users or tests.
  • The current structure makes dependency analysis and future modularization unnecessarily difficult.

There are also headers such as stru_fac.h that include pw_basis_k.h while only using ModulePW::PW_Basis_K through pointers, where a forward declaration should be sufficient.

Suggested direction

The PW headers could gradually be made to follow a conventional one-way dependency structure:

PW_Basis
  ^
  |
PW_Basis_Sup
  ^
  |
PW_Basis_Big

and likewise for the k-point hierarchy.

In particular:

  • pw_basis.h should not include pw_basis_sup.h or pw_basis_big.h.
  • pw_basis_k.h should not include pw_basis_k_big.h.
  • Users that actually need a derived class should include its header explicitly.
  • Headers that only use PW classes through pointers/references should prefer forward declarations where possible.
  • Unit-test targets should declare their real implementation dependencies explicitly rather than relying on transitive header exposure or accumulating additional mocks.

This does not necessarily need to be changed in one large patch. Removing the reverse includes incrementally and fixing the resulting explicit dependencies should make the PW module easier to maintain and make CMake target dependencies more reliable.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

RefactorRefactor ABACUS codes

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions