# For posterity: another of these CMake "hacks" — No CMAKE\_C\_COMPILER could be found.

**URL:** https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721
**Category:** Usage
**Tags:** os:windows, gen:vs
**Created:** [June 19, 2026, 5:15pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721 "2026-06-19T17:15:13Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![exoosh](https://discourse.cmake.org/user_avatar/discourse.cmake.org/exoosh/32/4077_2.png) [@exoosh](https://discourse.cmake.org/u/exoosh)
#### Post date: [June 19, 2026, 5:15pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/1 "2026-06-19T17:15:13Z")

</div>

So, CMake seems incapable of passing through `/pdbaltpath:%_PDB%` when given in a `CMakeLists.txt` (first learning). It _somehow_ ends up as `%%%%_PDB%%%%` which then will evaluate — assuming a `foobar.exe` — to `%%%foobar.pdb%%%` in the PE file. Using generator expressions (`$<1:...>`) didn’t help either.

So obviously one would start using a workaround like this dumped into a `Directory.Build.targets` (because the corresponding `.props` ends up too early in the MSBuild sequencing, so we need to delay things a bit):

```auto
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<Target Name="OverrideLinkerSwitches" AfterTargets="ComputeLinkSwitches" BeforeTargets="Link">
		<ItemGroup>
			<Link>
				<AdditionalOptions>%(Link.AdditionalOptions) /pdbaltpath:%_PDB%</AdditionalOptions>
			</Link>
		</ItemGroup>
	</Target>
</Project>

```

For those not “in the know” this manipulates the `<ItemGroup />` named `Link` _after_ it has been defined in the project file, if we assume a vanilla `.vcxproj` in order to append the linker switch to the end.

Well done, nothing to see here, move on.

Nope, not so! This is what trips up `CompilerIdCXX.vcxproj` (`Modules/CMakeDetermineCXXCompiler.cmake` ⇒ `Modules/CMakeFindBinUtils.cmake`) with:

> error MSB4096: The item “Debug\CMakeCXXCompilerId.obj” in item list “Link” does not define a value for metadata “AdditionalOptions”. In order to use this metadata, either qualify it by specifying %(Link.AdditionalOptions), or ensure that all items in this list define a value for this metadata.

Hmm, very interesting. Why would `Link` items _not_ have this metadata which gets set by every vanilla C/C++ `.vcxproj` file?! And why did I even ask?

Of course wasted a massive amount of time on this, because the CMake generator step for VS does considerably more than is conventional in this ecosystem and generates throwaway projects with paths hardcoded to the system and the CMake version and other goodness. It’s the Unix `./configure` bolted onto default VS builds for no particular reason.

At a minimum I would have expected that the underhanded detection mechanisms inhibit `Directory.Build.*` and friends (like with `ImportDirectoryBuildProps=false` and friends), so the developer can see the failure in the generated projects which then _do_ include them, but the detection with “out-of-tree” inside subdirectory (build dir underneath source dir) doesn’t accidentally catch ambient MSBuild stuff during its “ssssshhhhh”-phase.

Instead I have to work around CMake’s hacks now with this:

```auto
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<ItemDefinitionGroup>
		<Link><!-- Bolt the metadata onto the Link items now, using whatever may have been set before -->
			<AdditionalOptions>%(AdditionalOptions)</AdditionalOptions>
		</Link>
	</ItemDefinitionGroup>
	<Target Name="OverrideLinkerSwitches" AfterTargets="ComputeLinkSwitches" BeforeTargets="Link">
		<ItemGroup>
			<Link>
				<AdditionalOptions>%(Link.AdditionalOptions) /pdbaltpath:%_PDB%</AdditionalOptions>
			</Link>
		</ItemGroup>
	</Target>
</Project>

```

If you can tell I am no big fan of CMake, that’s no coincidence. But at least this way others will know how to work around it.

At least I got to drive `-Wdev --debug-find --debug-output --log-level=DEBUG` again.

[imagine a hide the pain Harold GIF here]

PS: it doesn’t find either, so this thread is equally valid for `CMAKE_CXX_COMPILER`.

---

<div class="post-metadata">

### Author: ![exoosh](https://discourse.cmake.org/user_avatar/discourse.cmake.org/exoosh/32/4077_2.png) [@exoosh](https://discourse.cmake.org/u/exoosh)
#### Post date: [June 19, 2026, 5:23pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/2 "2026-06-19T17:23:48Z")

</div>

FYI: place this into the first `<PropertyGroup />` in the `.vcxproj` and you’ll inhibit these:

```auto
    <ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>
    <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>

```

However, there are more alike (e.g. `ImportUserLocationsByWildcardBeforeMicrosoftCommonProps` … use grep). MSBuild has many extension mechanisms. Perhaps a subst-drive to an otherwise empty directory would be better than this, because even `%TEMP%` isn’t safe from ambient MSBuild extension files.

---

<div class="post-metadata">

### Author: ![benthevining](https://discourse.cmake.org/user_avatar/discourse.cmake.org/benthevining/32/1924_2.png) [@benthevining](https://discourse.cmake.org/u/benthevining)
#### Post date: [June 19, 2026, 8:07pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/3 "2026-06-19T20:07:12Z")

</div>

Did you try using bracket syntax, like `[[/pdbaltpath:%_PDB%]]`

It’s not super clear to me what exactly the goal is here, just that this isn’t the best way to accomplish it

---

<div class="post-metadata">

### Author: ![exoosh](https://discourse.cmake.org/user_avatar/discourse.cmake.org/exoosh/32/4077_2.png) [@exoosh](https://discourse.cmake.org/u/exoosh)
#### Post date: [June 19, 2026, 9:25pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/4 "2026-06-19T21:25:52Z")

</div>

Hi. The goal is to remove all but the file name from the PDB path that gets imbued into the binary. Symbol servers and matching the symbols does the rest. No full paths needed (the normal way is to store the full path to the PDB on the build system). For this to work the `%_PDB%` must not expand prior to passing it to the linker.

`%_PDB%` gets internally set during linking with `link.exe`.

I haven’t tried `[[/pdbaltpath:%_PDB%]]` and will give it a shot. Thanks. You’re referring to [these here](https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#bracket-argument), right?

---

<div class="post-metadata">

### Author: ![exoosh](https://discourse.cmake.org/user_avatar/discourse.cmake.org/exoosh/32/4077_2.png) [@exoosh](https://discourse.cmake.org/u/exoosh)
#### Post date: [June 19, 2026, 9:58pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/5 "2026-06-19T21:58:14Z")

</div>

> [@benthevining](#):
>
> Did you try using bracket syntax, like `[[/pdbaltpath:%_PDB%]]`

Tested now. The outcome is `/pdbaltpath:%%_PDB%%` as opposed to four `%` on either side.

---

<div class="post-metadata">

### Author: ![benthevining](https://discourse.cmake.org/user_avatar/discourse.cmake.org/benthevining/32/1924_2.png) [@benthevining](https://discourse.cmake.org/u/benthevining)
#### Post date: [June 19, 2026, 11:48pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/6 "2026-06-19T23:48:50Z")

</div>

Then this indeed sounds like a CMake bug, or at least undocumented behavior. Bracket arguments are supposed to not perform any escaping. Maybe @brad.king can offer some help here?

---

<div class="post-metadata">

### Author: ![exoosh](https://discourse.cmake.org/user_avatar/discourse.cmake.org/exoosh/32/4077_2.png) [@exoosh](https://discourse.cmake.org/u/exoosh)
#### Post date: [June 22, 2026, 8:45am UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/7 "2026-06-22T08:45:58Z")

</div>

Oh and here’s a hack for debugging what CMake is trying behind the scenes. Put this into a `Directory.Build.props` or `Directory.Build.targets` (as long as CMake doesn’t shut out ambient MSBuild extensions):

```auto
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<!-- Enable build command logging -->
	<PropertyGroup>
		<ThisProjectBuildLogFileName Condition="'$(MSBuildProjectName)' == ''">$(MSBuildThisFileDirectory)BuildCommandLines.log</ThisProjectBuildLogFileName>
		<ThisProjectBuildLogFileName Condition="'$(MSBuildProjectName)' != ''">$(MSBuildThisFileDirectory)BuildCommandLines-$(MSBuildProjectName).log</ThisProjectBuildLogFileName>
	</PropertyGroup>
	<Target Name="LogBuildCommands" BeforeTargets="SetUserMacroEnvironmentVariables;SetBuildDefaultEnvironmentVariables" Condition="'$(DisableLogBuildCommands)' != 'true'">
		<Message Text="Setting LOG_BUILD_COMMANDLINES='$(ThisProjectBuildLogFileName)'" />
		<SetEnv Name="LOG_BUILD_COMMANDLINES" Value="$(ThisProjectBuildLogFileName)" Prefix="false" />
	</Target>
</Project>

```

This will create a log file for each of these projects. So you’ll get `BuildCommandLines-CompilerIdC.log`, `BuildCommandLines-CompilerIdCXX.log` and then plenty of log files with randomly generated names. I am counting 138 such files in my build, which is plenty much on a system where process creation is way more costly than on Unix.

The `LOG_BUILD_COMMANDLINES` trick still doesn’t seem to be widely known, so perhaps this will help spread the word.

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [June 22, 2026, 11:00pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/8 "2026-06-22T23:00:32Z")

</div>

@exoosh the generators map CMake’s code model to the native build system. They are not meant to provide low-level control over the generated build files. Nor are the generated build files meant to be relocatable or standalone in any way. If you’re trying to do any of those things then you’re going to be frustrated because CMake isn’t meant for such purposes.

@benthevining bracket arguments quote literal content for passing to a CMake language command. Once the command receives them there is nothing special about what it does with them.

As for the use case raised here, we don’t currently provide a way to express `/pdbaltpath:%_PDB%` within CMake’s code model. See [CMake Issue 15865](https://gitlab.kitware.com/cmake/cmake/-/work_items/15865).

---

<div class="post-metadata">

### Author: ![exoosh](https://discourse.cmake.org/user_avatar/discourse.cmake.org/exoosh/32/4077_2.png) [@exoosh](https://discourse.cmake.org/u/exoosh)
#### Post date: [June 23, 2026, 3:11pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/9 "2026-06-23T15:11:38Z")

</div>

> [@brad.king](#):
>
> If you’re trying to do any of those things then you’re going to be frustrated because CMake isn’t meant for such purposes

@brad.king Hi, I am trying no such thing. I am aware of CMake’s limitations and that’s why I am not voluntarily “in team CMake”. But there are those times when one has to bite the bullet because someone else decided CMake’s the best thing since sliced bread and you are left with their legacy 😉 (usually it’s not even that simple).

Still, don’t you think that — given the nature of these CMake tests being run _silently_ — it might make sense for CMake to play nice with the MSBuild extension mechanisms at the disposal of the users?

To me it’s just another item on the long list of CMake idiosyncrasies known to me. But wouldn’t it make sense for CMake to shut out the most common MSBuild extension mechanisms so ambient configuration doesn’t silently fail the generator step?! I don’t find:

> No CMAKE\_CXX\_COMPILER could be found

to be very much to the point, given the underlying cause. I.e. with `ImportDirectoryBuildProps=false` and `ImportDirectoryBuildTargets=false`.

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [June 23, 2026, 3:15pm UTC](https://discourse.cmake.org/t/for-posterity-another-of-these-cmake-hacks-no-cmake-c-compiler-could-be-found/15721/10 "2026-06-23T15:15:57Z")

</div>

> [@exoosh](#):
>
> to play nice with the MSBuild extension mechanisms at the disposal of the users?

Please open [an issue](https://gitlab.kitware.com/cmake/cmake/-/work_items) to describe that problem and discuss possible solutions.
