How do I force cmake to use cl.exe without full path?

落花浮王杯 提交于 2019-12-10 10:23:07

问题


I am building an open source project (kst, v2.0.8) that uses CMake. I am using CMake v2.8.12.2 and MSVC 2008 as a compiler and am generating NMake makefiles to build it on the command line. I can get it to build successfully with this setup. These versions are mandated so I cannot currently use a later version of CMake or MSVC.

I need to be able to perform a source code analysis of kst using HP's Fortify and to be able to use it from the command line it works in one of two ways:

  1. Touchless mode where it creates it's own "cl.exe", sets the path to it before the path to the real cl.exe and therefore gets launched during build.

  2. Set the compiler in the makefile to the Fortify command line, e.g. sourceanalyzer -b build_id cl instead of cl.

Either way I need to force the compiler that cmake generates into its makefiles to be something that cmake does not automatically detect.

I've tried setting the compiler when running cmake following the same method in this question but cmake still insists on putting the full path to the MSVC cl.exe in the makefiles.

cmake -DCMAKE_C_COMPILER=cl -DCMAKE_C_COMPILER_FORCED=ON -DCMAKE_CXX_COMPILER=cl -DCMAKE_CXX_COMPILER_FORCED=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%CFITSIO_DIR% -G"NMake Makefiles" ..\cfit3250

I also tried setting the compiler to invoke Fortify but when cmake tests the compiler it fails saying that it cannot find the compiler. (I have also tried this without the FORCED=ON arguments and in that case it says the compiler fails.)

cmake -DCMAKE_C_COMPILER="sourceanalyzer -b %BUILDID% cl" -DCMAKE_C_COMPILER_FORCED=ON -DCMAKE_CXX_COMPILER="sourceanalyzer -b %BUILDID% cl" -DCMAKE_CXX_COMPILER_FORCED=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%CFITSIO_DIR% -G"NMake Makefiles" ..\cfit3250

I could probably search and replace all the compiler invocations in the makefiles but I'd have to remember to do that after every cmake, and it would be tedious seeing as there are multiple projects / makefiles / calls to cl (rather than defining a CC variable in the makefile). I'd rather have a way to make cmake use the desired compiler right from the offset.


回答1:


UPDATED: Testing showed the original suggested approach didn't work as expected on at least some platforms. It seems using a wrapper script is likely the way to go.

If you really want to force a particular compiler and by-pass CMake's compiler checks, the CMakeForceCompiler module may be what you are looking for. That link to the CMake docs contains a trivial toolchain file example which shows how to use a specific compiler invoked as a simple command with no path. Unfortunately, CMake still converts this to an absolute path, so on its own, this won't solve your problem. You could, however, use a toolchain file to point at a wrapper script and use CMakeForceCompiler to bypass the compiler checks. This combination should yield the behaviour you've asked for, but note that CMakeForceCompiler is now deprecated.

Note that when using the CMakeForceCompiler module, you take on a bit more responsibility for telling CMake information, notably the compiler ID of the particular compiler you want to force using, but from the CMake docs it seems pretty clear this will just be MSVC in your case.

To use a toolchain file, invoke CMake with a -DCMAKE_TOOLCHAIN_FILE=path/to/file option pointing at your own custom toolchain file. The CMake docs have a specific section covering the use of toolchains, although it does gloss over some of the important nitty gritty details.

As mentioned in @Tsyvarev's comment, the use of a wrapper script is likely to be your best way of dealing with this. That wrapper script just needs to forward the call to the usual compiler command without specifying a path. You then take responsibility for ensuring the command will be on your PATH when you do a build. Something as simple as the following should suffice as a wrapper batch file on Windows (untested):

cl %*

Now, you can control whether the Visual Studio compiler or Fortify gets invoked purely by the PATH the build sees. Personally, I think this is a bit fragile, but it's what you asked for. ;)

As a more robust alternative, is it possible to use two completely separate builds? If so, then I'd recommend that as a better alternative. Build one with the default Visual Studio compiler as normal and for the other build, use a toolchain file to point at the Fortify compiler to get CMake to bypass its compiler checks. That way you aren't relying on the build environment being set up a particular way.



来源:https://stackoverflow.com/questions/34906024/how-do-i-force-cmake-to-use-cl-exe-without-full-path

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!