Repository navigation
Ask clang what a target triple means instead of guessing from its text - #7
Merged
Merged
Conversation
GetClangCompileCommands returns the command line of each source file (CommandLine as a JSON array, WorkingDirectory, TargetIdentifier) without building anything, so design-time builds can run it. CoreCompile now runs those same commands. A ClangCompileCommand rule adds the target to the project subscription service. Argument expansion moves into ClangArguments, shared by ExeTask and the new ClangCompileCommand task. This also fixes response file quoting: an argument containing white space put its opening quote at the start of the whole file, breaking any command with a path containing a space.
Target identifiers become a configuration dimension, as target frameworks are in .NET projects: with ProjectConfigurationsDeclaredDimensions, providers supply Configuration (from Configurations), Platform (from Platforms) and TargetIdentifier (from TargetIdentifiers, a variant dimension), so every target identifier of the active configuration is loaded as its own configured project with its own design-time build. ClangCompileCommandSubscriber follows the active configuration group and collects each configured project's GetClangCompileCommands results into ClangCompileDatabase. ClangdLanguageClient starts clangd for the Clang content types, which now derive from the language server base type. ClangdProxy sits between Visual Studio and clangd and: - sends clangd every file's compile command once initialized, and again when a design-time build changes it; - advertises and answers textDocument/_vs_getProjectContexts, listing one context per project and target identifier; - switches the command clangd uses for a file when a request names another context; - gives headers the command of the nearest source file of each project. Grammars: drop the bundled Objective-C grammars, which shadowed Visual Studio's fuller built-in ones, and map .cppm, .ixx, .hxx and .ipp onto the built-in C++ grammar.
- Load every configured project of the active configuration group. The group of configured projects only holds those already loaded, so only the active target identifier was being followed and offered as a context. - Clear TargetIdentifier for real builds of multi-target projects (a build global properties provider, as .NET does for TargetFramework) so Build runs the cross-targeting build for every target identifier, not just the active one. - The SDK now resolves the compiler: ResolveClangTools finds clang (ClangToolPath, PATH, the LLVM installation, Visual Studio's Clang tools) and llvm-ar from the same installation, and asks clang for its resource directory. Builds use the resolved tools, and compile commands carry the compiler's full path and ResourceDirectory. - clangd is given the SDK compiler's resource directory, so it uses that compiler's builtin headers, and the clangd beside the SDK's compiler is preferred. - Pass the c modifier to llvm-ar so creating an archive is not reported as a build warning. - IKVM_CLANG_CLANGD_TRACE names a file to trace the messages between Visual Studio and clangd, the configuration dimensions and the compile commands collected from projects.
…hout it SDK: - ResolveLlvmToolset finds clang, clang++, llvm-ar and clangd together. LlvmToolsPath names one directory to take every tool from; ClangPath, ClangCxxPath, LlvmArPath, ClangdPath and LinkerPath override single tools. Otherwise the tools come from one installation: PATH and the platform's usual places (LLVM and Visual Studio's Clang tools on Windows, Homebrew on macOS, /usr/lib/llvm-N on Linux), preferring an installation with the whole suite over clang alone, and taking the other tools from clang's directory first. ClangToolPath/ClangToolExe and LlvmArToolPath/ LlvmArToolExe still work. - A tool that cannot be found, or an override naming a missing file, is reported with guidance (ICLANG1001-1003) and fails the build only where that tool is needed. Design-time builds still produce compile commands. - Projects with C++ or Objective-C++ sources link with clang++, so the C++ standard library is linked (clang alone omits it for non-MSVC targets); LinkWithClangCxx overrides. LinkerPath is passed as --ld-path. - GetLlvmToolset, with an LlvmToolset rule, reports the toolset and its problems to Visual Studio. - UseClangTasks=false works again: every inline task is compiled from all the task sources (with Evaluate="true"), which keep their usings inside the namespace so they can be joined. - IKVM.Clang.Sdk.Tasks.Tests covers the resolution rules. Extension: - clangd comes from the SDK (ClangdPath); ClangdLocator is gone. - Toolset problems appear as Error List warnings with the SDK's guidance; opening one opens the project file. They clear once corrected. - Without a usable clangd, activation waits and an info bar explains why and how to correct it. When a design-time build reports one, clangd starts and is given the documents already open. A project whose SDK does not report its toolset gets a message saying to update it.
Visual Studio's default project GUID storage writes a ProjectGuid property into every project it opens. The solution already records the GUID, so a storage provider for Clang projects keeps it in memory instead, while still using a GUID a project file already has. The .NET project system does the same.
- Builds recorded nothing in FileListAbsolute.txt: the files written were collected into items that were never combined, so Clean deleted nothing and outputs that were no longer produced were never removed. - Single-target projects had no Rebuild target; it now runs BeforeRebuild, Clean, Build and AfterRebuild. - Rebuild of a multi-target project depended on Clean and Build, which share the dispatch to the inner builds, so it only cleaned. It now has each inner build rebuild itself. - Clean also removes the outputs the SDK knows it produces (object files, the library or executable and its symbols, copied headers and the copies in the output directory), so outputs that were never recorded go too. - CleanTests cover Build, Clean and Rebuild for one and several target identifiers, and the removal of the object file of a deleted source.
- Compile with a new ClangCompile task: sources build in parallel, and a source is rebuilt when it, a header it includes (from clang's -MD dependency file) or its command line changes. - Relink executables and shared libraries when a referenced library or the link command changes; recreate archives so removed sources drop out. - Build references for the referencing project's target identifier, and report an error when a host build references a project with several. - Copy the shared libraries an executable needs, including ones reached through static libraries, next to it. - Build for the host when no target identifier is given. - Only name debug symbols that are produced, only copy headers marked CopyToIncludeDirectory, and stop adding /subsystem to every link. - Tests for each of these.
- Release builds pass -O2 and define NDEBUG. Optimization sets the level (per project or per file), and DefineNDEBUG turns the definition off. - PositionIndependentCode defaults to true on ELF targets, so static libraries can be linked into shared ones. Windows does not take -fPIC, Apple platforms are always position independent, and on WebAssembly it selects dynamic linking, so it stays off there. - The README's property table now describes TargetIdentifier and the Subsystem default as they are.
Clang already chooses for each target: on for Linux, Android, Apple and Windows, off for bare metal and FreeBSD. PositionIndependentCode now passes -fPIC when true and -fno-pic when false, and nothing otherwise.
A target triple is whatever clang makes of it, so the SDK no longer reads meaning into the string. A new ResolveClangTarget task asks clang, in parallel: how it normalizes the triple, which macros it predefines for it, and, by compiling an empty file, which object file format it produces. - Output names follow the object format: COFF is named as on Windows, Mach-O as on Apple, everything else as on Linux. UEFI, for one, now gets .obj and .lib, though its triple says nothing of Windows. - The MSVC environment, which decides whether a .pdb is expected, is told by clang defining _MSC_VER. - ClangTargetTriple, ClangObjectFormat and ClangTargetIsMsvc are set for the rest of the build, and GetOutputItem reports the first two. Setting ClangObjectFormat or ClangTargetIsMsvc in the project overrides clang. - A triple clang cannot build for fails the build with ICLANG3001 and what clang said; Clean and design-time builds still work. - Answers are kept in memory for the build process and in obj/ for later builds, keyed on the compiler, its timestamp and size, and the triple. - The naming properties are now set by the ResolveClangTarget target rather than at evaluation, and the string-matching ClangTargetOS is gone. - The executable test exits through ExitProcess, so the loader's threads no longer keep it running past the test's wait.
wasabii
force-pushed
the
clang-target-info
branch
2 times, most recently
from
October 6, 2026 23:29
df9e665 to
ece15f8
Compare
wasabii
marked this pull request as ready for review
October 6, 2026 23:31
wasabii
force-pushed
the
clang-target-info
branch
2 times, most recently
from
October 7, 2026 12:39
025610f to
15592bc
Compare
# Conflicts: # src/IKVM.Clang.Sdk.Tests/BuildTests.cs # src/IKVM.Clang.Sdk.Tests/ReferenceTests.cs # src/IKVM.Clang.Sdk.Tests/TestProjects.cs # src/IKVM.Clang.Sdk/targets/IKVM.Clang.Core.targets # src/IKVM.Clang.Sdk/targets/IKVM.Clang.NoTasks.targets # src/IKVM.Clang.Sdk/targets/IKVM.Clang.Tasks.targets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A target triple is whatever clang makes of it, so the SDK no longer reads
meaning into the string. A new ResolveClangTarget task asks clang, in
parallel: how it normalizes the triple, which macros it predefines for it,
and, by compiling an empty file, which object file format it produces.
Mach-O as on Apple, everything else as on Linux. UEFI, for one, now gets
.obj and .lib, though its triple says nothing of Windows.
by clang defining _MSC_VER.
the rest of the build, and GetOutputItem reports the first two. Setting
ClangObjectFormat or ClangTargetIsMsvc in the project overrides clang.
clang said; Clean and design-time builds still work.
builds, keyed on the compiler, its timestamp and size, and the triple.
rather than at evaluation, and the string-matching ClangTargetOS is gone.
no longer keep it running past the test's wait.
Stack created with GitHub Stacks CLI • Give Feedback 💬