`import std;` er litt knot

Publisert 13. januar 2026

Jeg har et nytt prosjekt på gang, som jeg ønsker å bruke som en plattform for å lære de nyeste konseptene i C++. Den nyeste standarden er i skrivende stund C++23, publisert i oktober 2024.

I følge Wikipedia er dette hvordan man nå skal skrive “Hello, world!” i C++23:

import std;

int main() {
    std::println("Hello, world!");
}

Her ser vi en av de best kjente endringene i C++23: de har lagt til en println-funksjon i standardbiblioteket! :eksploderende hode-emoji: (Det finnes også print, som fungerer som du forventer.)

En annen stor greie her finnes på første linje, artikkelens emne: import std;. Wikipedia-programmet bruker altså standardbiblioteket som en modul(!), ikke via header-filer. Denne muligheten er en ny del av C++23-standarden.

(Moduler har eksistert siden C++20, og gir deg en litt mer moderne opplevelse rundt å splitte kode i mange filer enn header- og kildefiler gjør. Det gir også store forbedringer i kompileringstid.)

Jeg ønsker å bruke C++23 for alt det er verdt i prosjektet mitt, så import std; må jeg selvsagt ha. Utviklingsmiljøet på min bærebare PC har relativt oppdaterte versjoner av ganske industristandard-komponenter:

  • macOS 26 (aarch64)
  • CLion 2025.3.1.1 (JetBrains sin C/C++-IDE)
  • CMake 4.2.1 (meta-byggesystem) (Homebrew)
  • Ninja 1.13.2 (byggesystem) (Homebrew)
  • LLVM 21.1.8 (inkl. clang/clang++, standardbibliotek, debugger, etc.) (Homebrew)

Å få disse komponentene til å spille på lag slik at “Wikipedia-programmet” kan kjøres har krevd overraskende mye magi. Jeg oppsummerer her de nødvendige faktorene å ta hensyn til, mesteparten også relevant for Linux.

Overbevise CMake om å kunne importere standardbiblioteket

Her er hva jeg tror er en nokså kryss-plattform CMake konfigurasjon, i allefall så lenge vi bruker clang. CMake støtter per i dag import std; som en eksperimentell egenskap. Vi må derfor, avhengig av versjon, skru på CMAKE_EXPERIMENTAL_CXX_IMPORT_STD-variabelen med en spesifikk UUID, som identifiserer den eksakte CMake-koden som skal kjøre for å skru på støtten. Alt dokumentert her.

cmake_minimum_required(VERSION 4.2)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")
set(CMAKE_CXX_COMPILER_IMPORT_STD 1)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi")

project(dans LANGUAGES CXX)

add_executable(dans main.cpp)
set_target_properties(dans PROPERTIES
    CXX_MODULE_STD 1
)

Videre er det slik at for clang er det bare LLVM-implementeringen (libc++) av standardbiblioteket som støttes som modul. (Man kan altså ikke bruke libstdc++, GNU-implementeringen.) Dette settes som flagg til kompilator og linker i vist konfigurasjon. Til slutt må vi spesifikt si at target (her dans) skal ha egenskapen CXX_MODULE_STD slått på.

Om man glemmer variabler her, eller setter de i feil rekkefølge i forhold til deklarasjonen av project(), kan man få kryptiske eller lite nyttige feilmeldinger. En spesielt smertefull situasjon kan oppstå om man (som jeg gjorde) går ut fra at det går bra å bare sette CMAKE_EXPERIMENTAL_CXX_IMPORT_STD til True. Da blir egenskapen ikke slått på, men gir heller ingen form for feilmelding.

Dette er fortsatt ikke helt nok konfigurasjon, fordi Clang-CXX-CXXImportStd.cmake altså CMake-koden som lastes når man skrur på den eksperimentelle støtten og bruker clang, ikke klarer å detektere en viktig fil på egenhånd: libc++.modules.json, manifestet til standardbibliotek-modulen.

Dette er et ganske bredt rapportert problem, og mange kilder foreslår denne løsningen, altså å redigere CMake-koden for å gi den nok informasjon til å finne manifestfilen. Mange av disse diskusjonene er gamle, og jeg føler ikke for å redigere kode distribuert av pakkebehandleren min. En kjapp sjekk av Clang-CXX-CXXImportStd.cmake viser at det siden har kommet en ny variabel: CMAKE_CXX_STDLIB_MODULES_JSON. Det er nok å sette denne til absolutt filbane for manifestet for å korrigere problemet. Denne løsningen har jeg ikke sett nevnt på noen form for nettsøk.

Til slutt (dette spesifikt fordi jeg bruker Homebrew, og ikke Apple sin innebygde distribusjon av LLVM) må vi instruere CMake om hvor den skal finne operativsystemets headerfiler og biblioteker å linke mot.

Jeg kjører altså CMake med følgende ekstra (plattformspesifikke) argumenter:

-DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
-DCMAKE_CXX_STDLIB_MODULES_JSON=/opt/homebrew/opt/llvm/lib/c++/libc++.modules.json

Vi har nå en CMake-konfigurasjon som under verktøykassa fra Homebrew lar oss kjøre og debugge Wikipedia-programmet i og utenfor CLion.

La CLion se standardbiblioteket som en modul

Selv om vi nå har en byggbar CMake-konfigurasjon, får vi feilmeldinger relatert til standardbibliotek-import i CLion, som er plagsomme og gjør at vi ikke får noen form for hjelp i IDE-en. Dette har vært et kjent problem i CLion siden august 2024, tilsynelatende uten noen fiks annet enn nødløsningen foreslått i kommentaren.

Jeg har endt opp med å legge til følgende ekstra (funksjonelt unødvendige) CMake-mål kun for at CLion skal plukke opp standardbibliotek-modulen i sin indeksering.

# Hack to make CLion happy with `import std;`
add_library(unused_std_target STATIC)
target_sources(unused_std_target
    PRIVATE
    FILE_SET CXX_MODULES
    BASE_DIRS /opt/homebrew/opt/llvm/share/libc++/v1
    FILES /opt/homebrew/opt/llvm/share/libc++/v1/std.cppm
        /opt/homebrew/opt/llvm/share/libc++/v1/std.compat.cppm
)

(Her med spesifikke filbaner for min LLVM-installasjon.)

I konklusjon

Jeg har nå et greit utviklingsmiljø for å jobbe med C++23, men forstår absolutt hvorfor prosjekter ofte er treige på å adoptere nye C++-standarder. Gleder meg til å få dette til å funke på Linux (og gcc) også…

Mesteparten av problemene her kom ikke av at jeg bare ville bruke import std;, men heller fordi jeg også ville ha alle de andre fine greiene rundt. CLion støtter CMake absolutt best, og CMake er for alle sine feil utvilsomt standardverktøyet for å bygge C++-prosjekter. Dette er mye mer verktøy enn hva kan rettferdiggjøres for “Hello, world!”, men vil forhåpentligvis lønne seg i lengden etterhvert som prosjektet legger til avhengigheter og sine egne biblioteker og interne moduler.

Følg med for å se hva det blir til!