|
# Compiler options, common to both scanning dependencies and building header units. |
|
clOptions = ['/exportHeader', '/headerName:angle', '/translateInclude', '/Fo', '/MP'] |
|
|
|
# Store the list of headers to build. |
|
allHeaders = getAllHeaders(os.path.join(litConfig.cxx_headers, 'header-units.json')) |
|
|
|
# Generate JSON files that record how these headers depend on one another. |
|
if noisyProgress: |
|
print('Scanning dependencies...') |
|
cmd = [test.cxx, *test.flags, *test.compileFlags, *clOptions, '/scanDependencies', '.\\', *allHeaders] |
|
yield TestStep(cmd, shared.execDir, shared.env, False) |
|
|
|
# The JSON files also record what object files will be produced. |
|
# IFC filenames and OBJ filenames follow different patterns. For example: |
|
# <filesystem> produces filesystem.ifc and filesystem.obj |
|
# <xbit_ops.h> produces xbit_ops.h.ifc and xbit_ops.obj |
|
# We can easily synthesize IFC filenames, but it's easier to get the OBJ filenames from the JSON files. |
|
|
|
# This dictionary powers the topological sort. |
|
# Key: Header name, e.g. 'bitset'. |
|
# Value: List of dependencies that remain to be built, e.g. ['iosfwd', 'limits', 'xstring']. |
|
remainingDependencies = {} |
|
|
|
# Read the JSON files, storing the results in objFilenames and remainingDependencies. |
|
for hdr in allHeaders: |
|
with open(os.path.join(outputDir, f'{hdr}.module.json')) as file: |
|
jsonObject = json.load(file) |
|
objFilenames.append(jsonObject['rules'][0]['primary-output']) |
|
remainingDependencies[hdr] = [req['logical-name'] for req in jsonObject['rules'][0]['requires']] |
|
|
|
# Build header units in topologically sorted order. |
|
while len(remainingDependencies) > 0: |
|
# When a header has no remaining dependencies, it is ready to be built. |
|
readyToBuild = [hdr for hdr, dep in remainingDependencies.items() if len(dep) == 0] |
|
|
|
# Each layer can be built in parallel. |
|
if noisyProgress: |
|
print('Building deduplicated header units:', ' '.join(readyToBuild)) |
|
cmd = [test.cxx, *test.flags, *test.compileFlags, *clOptions, *consumeBuiltHeaderUnits, *readyToBuild] |
|
yield TestStep(cmd, shared.execDir, shared.env, False) |
|
|
|
# Update remainingDependencies by doing two things. |
|
# hdr, dep is the current key-value pair. |
|
# First, keep `if len(dep) > 0`. (Otherwise, we just built hdr.) |
|
# Second, filter dep, eliminating anything that appears in readyToBuild. (If we're left with |
|
# an empty list, then hdr will be ready to build in the next iteration.) |
|
remainingDependencies = { |
|
hdr: [d for d in dep if d not in readyToBuild] |
|
for hdr, dep in remainingDependencies.items() if len(dep) > 0 |
|
} |
|
|
|
# Add compiler options to consume the header units that we just built. |
|
for hdr in readyToBuild: |
|
consumeBuiltHeaderUnits += ['/headerUnit:angle', f'{hdr}={hdr}.ifc'] |
📜 Documentation
stdandstd.compatstdAndstd.compat#2930🚧 Status
stdAndstd.compat#3108stdandstd.compatare available when compiling in C++20 mode.#include <meow>can coexist withimport std;in the same translation unit, in that order.extern "C++"as a temporary workaround for#include/importcoexistence #4154import std;before#include <meow>, will still cause compiler errors. We're working on a long-term solution.We've reported the following compiler bugs; this issue is for tracking the status of these compiler bugs and removing workarounds/adding test coverage as compiler fixes are released. As you can see below, a ton of compiler bugs have been fixed. If you're using header units or named modules, I strongly recommend using the latest version of VS 2022.
As
/clrC++20 support is a work in progress, we are not yet testing Standard Library Header Units or Modules under/clr.❌ Clang
🐛 EDG (IntelliSense Front-End)
🐞 Active, C1XX (MSVC Front-End)
<filesystem>: compiler error usingdirectory_iterator/recursive_directory_iteratorinside a struct/class with modules #3661stdmodule to export too much stuff.std::coutproperly"<thread>: Usingthis_thread::sleep_forin a module results in compilation errors #5203❔ Possible Improvements (C1XX/MSBuild)
import std.compat;,std::printf, orstd::cout"import std;is seen, butstd.ifc/std.objneed to be built"import std;andimport std.compat;"🩹 Permanent Workarounds
std::projected::operator*()error LNK2019: unresolved external symbol"abort().😻 Fixed, Workaround Removed
'std::pointer_traits<_Voidptr>': more than one partial specialization matches the template argument list"__pragma(warning(disable : 4996))doesn't take effect"'std::char_traits'"std::_Yarn<char>::operator=(char const *)already defined"std::optional,c1xx!FindConversionFunctions()assertion failed:PF_ISSET(ParsingClassTemplateDefn)"std::variant,c1xx!Module::InterfaceReader::materialize_function()assertion failed"'std::ranges::operator ==': a trailingrequiresclause is only allowed on a templated function"/headerUnit:angleICEs"queue'sfriend bool operator=="/headerUnit:angle vector=vector.ifcheader-units.jsonvia/sourceDependencies:directivesand/translateInclude/exportHeader /headerName:angle algorithm type_traits vector_Nontrivial_dummy_type's constructor"type_info's equality operator"<format>as a header unit"_CrtGetAllocHookemits warning C5106: macro redefined with different parameter names"convertible_toconstrains a constructor"<ranges>compiler assertion:previous_element == tokenInputStack.TopOfStack(), aliastemplates.cpp 1010"template <int = 0>tovformat()emits warnings C4265 and C4365"#pragma warningdoesn't always suppress warnings in templates"/scanDependenciesgenerates incorrect"logical-name"in JSON output"fatal error C1116: unrecoverable error importing module, with<concepts>"fatal error C1116: unrecoverable error importing module ''"error C2672: 'count_if': no matching overloaded function found"chrono::daysemits bogus error C2131"<chrono>emits fatal error C1116: unrecoverable error importing header unit'<chrono>'"std.ixxemits fatal error C1011: cannot locate standard module interface"extern "C"function declarations takingextern "C"types emit bogus error LNK2019: unresolved external symbol"extern "C"function mentioning entity with module linkage is being marked with module linkage"Module::InterfaceReader::materialize_function<Module::helpers::MemberBuilder>()"construct_atSFINAE causes Modules bogus error C2660: 'operator new': function does not take 3 arguments"<codecvt>: fatal error C1001: Internal compiler error.<any>: error C2679: binary'!=': no operator found which takes a right-hand operand of type'const type_info'(or there is no acceptable conversion)<memory>: error C2679: binary'==': no operator found which takes a right-hand operand of type'const type_info'(or there is no acceptable conversion)<functional>: error C2027: use of undefined type'type_info'<typeinfo>: error C2872:'type_info': ambiguous symbol<typeindex>: error C2440: 'initializing': cannot convert from 'initializer list' to'std::type_index'<regex>: Assertion failed:Nerrors > 0, fileD:\msvc\src\vctools\Compiler\CxxFE\sl\p1\c\trees.c/d1ifcInlineFunctionsasserts(bits::rep(typeEncoding.basicEncoding_) & 0x0000000F) != 0forprintf(_Format, ...)"<expected>ICEs withAssertion failed: IsInClassDefn()"'_Iterator_base12': the symbol to the left of a'::'must be a type"operator&"<ranges>: could not use std::views::istream StephanTLavavej/STL#13 VSO-1581022 "Standard Library Modules:inline constexprvariables forranges::viewsemiterror LNK2019: unresolved external symbol"'memcpy_s'because it has internal linkage"extern "C++"is directly applied to a class with a static member function"<ranges>: ICE with std::views::join_with StephanTLavavej/STL#17 VSO-1582910 "Standard Library Modules: ICE withstd::views::join_with"<variant>: Constructor inheritance causes ICE when class in named module inherits from class imported frommodule stdStephanTLavavej/STL#18 VSO-1582916 "Standard Library Modules: ICE when class in named module inherits fromvariantwith inheriting constructors"chunk_viewof input iterators"inserted, file template.cpp, line 10275"IsInClassDefn() && (region->owner == SU_TAG), file reader.cpp, line 2592"<fstream>: Importing as a header unit leads to error C2079: undefined class'std::basic_ofstream<char,std::char_traits<char>>'"destroy_at()emits bogus error C2131: expression did not evaluate to a constant"iota_viewemits bogus error C7608: atomic constraint should be a constant expression"constexpr vector::resize()ICE"<ranges>: Usage ofranges::iterator_tcauses ICE StephanTLavavej/STL#23 VSO-1584629 "Standard Library Modules: Usage ofranges::iterator_tcauses ICE"<atomic>: Building a header unit with/ZIemits warning C5260 #3287 VSO-1706387 "<atomic>: Building a header unit with/ZIemits warning C5260"source_location::column()misbehaves in user headers"'std::filesystem::_Dir_enum_impl': base class undefined #3333 VSO-1715231 "Standard Library Modules: Bogus error C2504:'std::filesystem::_Dir_enum_impl': base class undefined"charconvgives wrong result"using namespace std::chrono;for UDLs emits bogus error C3688: invalid literal suffix"/analyzeICE"osyncstreammove assignment emits bogus error C3083:'basic_ostream<char,std::char_traits<char> >': the symbol to the left of a'::'must be a type"sort()emits bogus error C2065:'_Atomic_counter_t': undeclared identifier"<format> + <chrono>: Could not format durations StephanTLavavej/STL#14 VSO-1582358 "Standard Library Modules:chronoformatting emits bogus error C3861:'_Fill_tm': identifier not found"<chrono>: Spurious warning C4702: unreachable code StephanTLavavej/STL#15 VSO-1582381 "Standard Library Modules: Bogus warning C4702: unreachable code"'#include <meow>'in the purview of module'std'appears erroneous"tuplechanges"<format>causes C4296 warning that need to be suppressed every time" (with header units)static constexprdata members"std::expectederror C2280 attempting to reference a deleted function"std::views::iotain member function in module causes ICE"std::views::repeatin member functions gives bogus error about lack ofcompareheader"'...': there are no parameter packs available to expand module"numeric_limits"ctype<char>::table_sizeshould be a compile-time constant"std::mdspanis unusable with C++20 modules"std::basic_string_viewsymbols""<chrono>year_month_weekdayandyear_month_weekday_lastemit bogus error C2131: expression did not evaluate to a constant"day{31}initializers emits 'not yet implemented' internal compiler error"extern "C++"doesn't avoid all problems when mixing includes and imports"extern "C++"interferes with ADL"std::filesystem::path::generic_string()in a module unit"'std'when constructing and exporting astd::chrono::zoned_timeobject"chrono::time_pointformatting emits bogus error C3861:'_Fill_tm': identifier not found"utc_clock::now()emits fatal error C1116: unrecoverable error importing module'std'."'std'. Specialization of'std::invoke_result_t'with arguments'_Fn, _Ty...'"std::views::zipwithstd::views::iotain C++20 module results in C1001 Internal compiler error"std::formatterin module is not found in other module."'promise_type': is not a member of'std::coroutine_traits<TestModule::FireAndForget>'#4826std::stacktrace"std::formatin a module requires including<format>header in .cpp files using that module"/Zc:preprocessordoes not terminate macro definitions properly"/scanDependenciesfor header units__msvc_formatter.hpp"static inlinefunctions cannot be called when using modules"<ctime>:time()/localtime()/mktime()emit error C2129: static function declared but not defined StephanTLavavej/STL#21constexprmember functions in different headers fails to compile"'std::_Unsigned128': no appropriate default constructor available"uniform_real_distributionemits error C2512:'std::_Unsigned128': no appropriate default constructor available #4899generate_canonicalcauses C1XX ICE:find_pending_comparison_function_for_definition(function) == std::end(pending_comparison_functions_for_definition)"🏗️ Building Deduplicated Header Units
Here's the part of our Python-powered test harness that builds "deduplicated" header units by topologically sorting them:
STL/tests/std/tests/P1502R1_standard_library_header_units/custom_format.py
Lines 56 to 109 in ef62d3f
With a bit of work, this can be extracted into a standalone Python script. (With significantly more work, it could be converted into CMake.)