Skipping compiler detection for a custom toolchain

I’m trying to write a toolchain file for a custom C / C++ toolchain. I’ve tried doing this in my toolchain file:

    set(CMAKE_C_COMPILER /path/to/c/compiler)
    set(CMAKE_CXX_COMPILER /path/to/cxx/compiler)

    set(CMAKE_C_COMPILER_ID id)
    set(CMAKE_CXX_COMPILER_ID id)
    set(CMAKE_C_COMPILER_VERSION version)
    set(CMAKE_CXX_COMPILER_VERSION version)

    set(CMAKE_C_COMPILER_WORKS 1)
    set(CMAKE_CXX_COMPILER_WORKS 1)

But it’s still trying to do a lot of feature detection, which breaks unless I go do surgery on the CMake module code.

The documentation for CMakeForceCompiler says that CMake can be taught to detect any kind of toolchain, but this doesn’t seem to be true in my case. This particular toolchain is hard-locked to a Visual Studio solution, and the automatically generated sln and main.cpp files that cmake tries to compile when the generator is Visual Studio do not contain valid code for this particular toolchain. I’m willing to do whatever it takes to make this work, even if it’s undocumented, gross, or ugly. I’m very motivated :slight_smile:

Is there anything I can do to force skip the feature detection step? One idea I have is to do the surgery on the cmake modules to get it to all pass, then copy/paste all of the auto-detected values into a toolchain file, and then set a magic variable to really force cmake to skip it all. But I can’t find a magic variable that will do this. Does anyone have any suggestions for me?

I’m pretty convinced at this point that my only way out here is going to be to somehow convince CMake to never, ever, ever try running the compiler during the configure step. Is this possible?

I don’t think that’s possible in general as try_compile and friends will be…lost without such a mechanism.

I think the way to do this is to make your toolchain work through CMake’s -T argument so that it just tells VS to use your toolchain (this is how Intel Fortran and clang-cl support in VS work AFAIK).

My situation is a little unique. This is for a video game console toolchain, which has very tight hooks into MSBuild. And it also requires some very unique syntax when doing compilation. And it’s supported by a Visual Studio extension provided by the console vendor, that installs hooks into MSBuild. The standard vcxproj that is generated by cmake (VS-10.vcxproj.in) is not correct for this particular toolchain setup, because it requires a certain Property sheet to be imported in the generated MSBuild, and it requires a different syntax for the main function. So there’s just no way I can find to do this without doing surgery on the builtin modules.

I’d actually be fine making the assumption “our cmake never runs try_compile”, because I already have perfect information about the compiler ahead of time, and there’s no reason for me to “try” anything.

I actually have CMake working with this toolchain today, but we’ve forked CMake’s module files, and it makes it a huge pain every time we want to upgrade to a new CMake version.

In my experience try_compile generates a very simple CMakeLists.txt file which then essentially runs CMake to generate a project. You can see these files by using --debug-trycompile.

If CMake cannot make a working project to compile a single source code file then it seems highly unlikely that it could create a working project for the source code you want to use.

I can run a post processor on the generated projects to fix up the 1-2 broken MSBuild tags. I already know this to be a working solution because I’ve done surgery on the CMake module code and actually gotten it working with the toolchain. All I need is to tell CMake “the compiler really does work, and I know the complete universe of information about its configuration in advance, so please trust me. I promise not to call try_compile”. Is this possible?

Is it the compilation or the linking part of the try_compile() call that fails? If it is just the linking part, then you could try changing the type of target the try_compile() call creates. You would do that with the CMAKE_TRY_COMPILE_TARGET_TYPE variable, which you could set to STATIC_LIBRARY. This will mean there is no linking step, only an archiving tool (which is much less likely to fail for typical cases).

I can try that tomorrow, my gut says it won’t be sufficient but I didn’t know about that option so I’ll report back once I try

It’d be nice to get this logic into CMake itself, but I suspect there are NDA terms around here :frowning: . Maybe a generic mechanism to do this that can be configured to do the NDA things would be sufficient (unless what even needs poked is NDA’d…)?

You can also adjust the MSBuild properties at CMake by injecting your own .props files

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets">
	<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>	  

  <ImportGroup>
    <!-- put your .props files here -->
  </ImportGroup>
</Project>

And use that file with VS_USER_PROPS target property. There is no CMAKE_* variable to initialize this property, though. The variable would be needed to make it compatible with try_compile().

To do that from a toolchain file, define a function in the toolchain file that you can later call for your targets.