How can I change MSVC compiler version in a CMAKE project? - c++

Since microsoft broke the compiler (again) in version 14.29.30037 (reported as 19.29.30038.1 by CMAKE for some reason) (look here) I need to go back to 14.28.something. I already downloaded 14.28.29910 through Visual Studio Installer and my Microsoft Visual Studio\2019\Community\VC\Tools\MSVC folder now contains folders with both versions.
However I can't find a way to force CMAKE to use this particular older version. I use CLion CMAKE integration and my settings look like this.
Please note that I've already tried setting Make, C Compiler and C++ Compiler paths to their counterparts in older compiler. This results in CMAKE reporting the desired 19.28.29915.0 compiler version (love the number of different versioning conventions microsoft uses by the way). Despite that, when I try to build the project I get the following:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\yvals_core.h(541): fatal error C1189: #error: STL1001: Unexpected compiler version, expected MSVC 19.29 or newer.
NMAKE : fatal error U1077: 'C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1428~1.299\bin\HostX86\x64\cl.exe' : return code '0x2'
Stop.
I guess this implies that not all parts of the compiler (some includes in this case) were switched to the old version.
If for some reason any piece of my code would help you with answering this question, the repo is available here
Please also note that despite how much I'd love to simply switch to GCC, I cannot because of CUDA support on Windows. I also cannot use different (older) Visual Studio version as the project requires C++ 20. Also, bonus question: How is it possible for a company as relevant as microsoft to literally break an enterprise-class development tool?

The following solution helped me:
Find vcvarsall.bat in the directory with your Visual Studio installation. (I have Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvarsall.bat)
Run vcvarsall.bat <your_arch> -vcvars_ver=<msvc_version>. In your case, put -vcvars_ver=14.28. Example of <your_arch> is amd64. This will set all the environment variables for desired MSVC version.
Start CLion from the command line with the created environment.

Related

Error: No CMAKE_Fortran_COMPILER could be found for Visual Studio 2019 Fortran support

I am using CMAKE to build Open Source Projects (like those are available at GitHub etc.) and I also have installed Visual Studio 2019. There is a problem that CMAKE can not find Fortran compiler in my system whereas I've installed MinGW with Fortran compiler. The error is:
**The Fortran compiler identification is unknown**
**No CMAKE_Fortran_COMPILER could be found.**
How can I solve this problem and make CMAKE be aware of Fortran compiler?
Note: I tried other projects that does not require Fortran compiler and those are built successfully.
Installed software:
CMAKE 3.18.5,
Visual Studio 2019,
MinGW
You need to show where your fortran executable file to CMakeList.txt like
set(CMAKE_Fortran_COMPILER "C:/MinGW/bin/gfortran.exe")
EDIT 2 for Visual studio 2019:
If you want to produce Visual Studio 2019 solution
Download Intel® oneAPI HPC Toolkit here.
If cmake cannot find Fortran compiler add a cmake flag CMAKE_Fortran_COMPILER with the value of ifort.exe path that u installed above. Like %install_path%/Intel/oneAPI/compiler/2021.1.1/windows/bin/intel64/ifort.exe
Configure and generate solution.
EDIT:
Alright, now I understand why you get this error. The Visual Studio generator does not support MinGW gfortran. They are totally separate ecosystems.
Remove your build directory and create a fresh one. Then use cmake .. -G "MinGW Makefiles" instead. I tried from CLI prompt of msys and successfully obtained the libraries from Windows machine.
If you are using Intel processors, you should first set-up Fortran environment for Visual Studio 2019
Better to check compilation guide and some troubleshooting Fortran Integration Issues with visual studio

Command to Read file in CMake

Does anyone know of a way to read from a file in CMake, that works in Visual Studio? I have a cross-platform App. in Visual Studio 2017 that compiles with a toolchain in Linux, running in Hyper-V.
I have a simple defined version number in one of my H-files that I would like to read, parse, and append version number to the name of the compiled program (e.g., company_app_1.2.3).
I can't seem to get the file(READ) command to work. Visual Studio is using CMake version 3.11. I assume CMake can do this regardless of the g++ toolchain being used.
Command I tried:
#Read version
-file(READ FileNameHere $sValue)
Visual Studio Error I get:
1>/bin/sh: -c: line 0: syntax error near unexpected token `READ'
The MakeFile does not have a .txt extension, of follow Visual Studio's naming convention, but I would be willing to rename it if there was an advantage (intellisense available, or some more info about the error).
Thanks in advance for any replies.

SCons detects Visual C++ v14.2 (2019) but not v14.1 (2017)

I need to build a dependency that uses SCons, and I need to build it with VC++2017, because another dependency I have cannot be built with VC++2019.
SCons successfully detects VC++2019 (v14.2), but not VC++2017 (v14.1):
c:\Python27\Scripts\scons [...] --msvc-version=14.1 [...]
scons: Reading SConscript files ...
scons version: 3.1.1
python version: 2 7 13 'final' 0
scons: warning: VC version 14.1 not installed. C/C++ compilers are most likely not set correctly.
Installed versions are: ['14.2', '14.0', '11.0']
[...]
C++ compiler $CC does not work
I have installed Visual Studio 2019 Enterprise as well as Visual Studio 2019 Build Tools, and for both, I have installed the platform tools / compiler for v14.1 and x86/x64. Compiling with the VC++2017 platform tools works fine in Visual Studio 2019 as well as using MSBuild, so the problem seems to be with SCons only.
How does SCons detect VC++2017 and VC++2019 and where should I start looking for the problem?
(There are old threads about this, but most of them are about people wondering why the "classic" detection/config methods using registry and vcvars.bat no longer work, so these are not helpful)
For current scons, it will believe what it gets back from vswhere.exe for the versions where that tool is considered definitive - 2017 and 2019. You can try seeing what that gives you.
vswhere -products * -property installationPath
That information is used to help locate the desired vars.bat file which imports the seetings needed.
I have found a perfect and simple solution:
Open file MSCommon/vc.py, find line: vc_pdir = os.path.join(vsdir[0], 'VC')
Change [0] to [1]
Re-build, the python will use vs2017
The reason is: if you install multi vs versions, the vsdir[0] is the highest one
Update: This is still (2021-09-16) an issue, and a simple workaround may be this answer - My answer also has a workaround, but it is more complicated and mostly for educational purposes on how recent versions of VC++ compilers can be detected and are (not properly) detected by SCons. You may also want to use my workaround if you are creating a build script for a build server or multiple development machines with varying setups.
The current version of SCons does not support selecting MSVC v14.1 (aka "Visual C++ 2017") if Visual Studio 2019 is installed, but Visual Studio 2017 is not. I confirmed this by looking at the code of SCons (see below).
An alternative approach is to use the --msvc-script option instead of --msvc-version.
In the MSVC installation folder, typically c:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\, you will find a file called vcvarsall.bat. If you run this without arguments, you will see that you can give it arguments for target platform and tools version, e.g.,
vcvarsall.bat x86 10.0.17763.0 -vcvars_ver=14.1
to compile for x86 (32-bit), Windows SDK version 10.0.17763.0 and tools version 14.1 (Visual C++ 2017).
Once you have found a command line for vcvarsall.bat that suits you, put it into a new BAT file that you create, say myvcconfig.bat (You have to use the complete path to vcvarsall.bat), then use the following command-line switch to SCons: --msvc-script=myvcconfig.bat.
*** Notes ***
Some parameters to SCons are redundant and will not work with --msvc-script, for example --32. SCons will tell you about them, so just remove them from the command-line.
The installation path of Visual Studio may be different from the one I provided above. You can find the installation path using Microsoft's own VSWhere tool. See also Locate Visual Studio
Visual Studio 2019 and Visual Studio Build Tools 2019 are separate installations with separate build tools. You can detect and use the vcvarsall.bat files of either ones. For example, if you are setting up a toolchain for a build server, you may want to use Visual Studio Build Tools 2019. If you just want to build one library one time (as in my case), just use the Visual Studio that is installed on your dev machine.
In case you are interested in how SCons detects MSVC and why it doesn't work, you can look at the source code in SCons/Tool/MSCommon/vc.py. You can clone the SCons GIT repository.
UPDATE: The following comment in vc.py (as of 2021-09-16) shows why this is still an issue in SCons and why this workaround is needed if you have both VC2017 and VC2019 compilers installed:
# make sure the cl.exe exists meaning the tool is installed
if ver_num > 14:
# 2017 and newer allowed multiple versions of the VC toolset to be
# installed at the same time. This changes the layout.
# Just get the default tool version for now
#TODO: support setting a specific minor VC version
Direct link (valid at time of writing)

Need more explanation on LNK2038 mismatch dectected for '_MSC_VER'

I inherited an old program from a colleague that is no longer with the company. It's an CPLEX optimization we use. It was built in house in C++ using Visual Studio 2005 and CPLEX121. The server where it's located is being decommissioned and we're trying to migrate it to a new server. I'm trying to rebuild the new application in Visual Studio 2013 using CPLEX126 for the optimizations.
Error I get is:
Description:
error LNK2038: mismatch detected for '_MSC_VER': value '1600' doesn't match value '1800' in (project name).obj
File:
ilocplex.lib(ilocplex.obj)
There are quite a few of these mismatches. I'm new to Visual Studio and C++, but I've managed to work through getting the CPLEX links updated, and now this error is happening.
From this forum post:
error LNK2038: mismatch detected for '_MSC_VER': value '1600' doesn't match value '1700' in CppFile1.obj
I've been able to deduce there might be something I can do to the toolset or "recompile my libraries" this seemed to work for some people on the last post, but all I need more specific help on how exactly to do that.
No, it's the object files. What the compiler emits. They appear to be inside the .lib file. You'll need to recompile it. – David Heffernan Oct 24 '13 at 20:40
Hi David, iam new to c++ .Iam basically a c# programmmer. Can you please elaborate the comments – user1654136 Oct 24 '13 at 20:43
2
The compiler is telling you to recompile Projectname1.lib with VS2012. – David Heffernan Oct 24 '13 at 20:48
I have no idea what that means and I don't have enough reputation to comment.
Also,
for each project in your solution make sure that
Properties > Config. Properties > General > Platform Toolset
is one for all of them, v100 for visual studio 2010, v110 for visual studio 2012
you also may be working on v100 from visual studio 2012
the response is "That worked for me"
My Project's Platform Toolset is "Visual Studio 2013 (v120)". Do I need to add some other toolset? there's no other option in the dropdown.
There is also a block of code in the .cpp file:
// set up Visual Studio version
#define _VS2005_
# if _MSC_VER < 1400
# undef _VS2005_
# endif
I also don't know what this is doing to see if it is causing the error.
First - you will not be able to recompile the CPLEX library because you will not have the source code and there is no way you are going to get it unless you work in the R&D team inside IBM. So forget that line of reasoning. You are dependent on IBM providing a pre-built library that works with the version of the compiler that you are using.
When you say that you "managed to work through getting the CPLEX links updated, and now this error is happening", I am guessing that you managed to update the paths to the C++ include files that are used by the compiler, so your compilation errors have gone away. But you may not yet have updated the library paths to show the compiler the right sets of libraries to link with.
From the error you are posting, '_MSC_VER': value '1600' doesn't match value '1800', that says to me that you are trying to link with the CPLEX library built for VS2010, while your code was compiled using VS2013. See for example How to Detect if I'm Compiling Code With Visual Studio 2008?
If you are new to C++, it is plain crazy for anyone to expect you to walk into a large existing code base and try to port to new compiler and libs and get it to run straight away without doing a bit more research and background learning. Have you tried to build and run the C++ examples provided with CPLEX?
Have you read the instructions for setting up a C++ project with CPLEX? They are in a file c_cpp.html in the CPLEX folder.
Now, I don't know that CPLEX has libraries for VS2013. I haven't got 12.6 here, so I can't be sure. Have a look in your installed copy of CPLEX, probably something like:
C:\Program Files\IBM\ILOG\CPLEX_Studio126\cplex\lib
...and that should tell you what versions of VS are supported. I have x64_windows_vs2008, x64_windows_vs2010 and x64_windows_vs2012
If there isn't a copy of the library for VS2013, then I think you are going to have to go back to VS2012 or VS2010. There may be a way to configure VS2013 to make it work like VS2012 and trick it onto generating code that is compatible; but I am guessing that would not be a "supported configuration" from IBM's perspective.
The stuff about #define VS2005 is using the C++ pre-processor to define a symbol which can be used to turn on or off bits of your source code. Look for where in your source code that symbol is used. I am guessing that is entirely separate from your linking issue. You might choose to do something similar if you make changes in your code to make it work (or work better) with the newer version of the compiler and libraries.
Tim's answer is entirely correct, but here's the piece that he couldn't check...
There doesn't exist CPLEX libraries for VS2013, so you should not spend time looking for some... This can be seen in this report, which you can access for other platforms/versions from the CPLEX Optimization Studio Detailed System Requirements.
This means that you will have to use Visual Studio 2012 compiler. You can still use the Visual Studio 2013 environment: what you have to do is to install both versions and instruct Visual Studio 2013 to use the compiler from version 2012 by changing the Platform Toolset. But all the other libraries that your application uses must then have been compiled by the Visual Studio 2012 compiler. You can't mix and match...

How run clang from command line on Windows?

At the Going Native conference last week, Chandler Carruth announced the existence of prebuilt binaries for running clang on windows. The same information is in a blog post here. The intended audience for this is users of Visual Studio, but I want to run clang from the command line.
I ran the installer and added the LLVM bin directory to my path, but when I try to compile "Hello world", I get this:
C:\>clang hello.cpp
hello.cpp:1:10: fatal error: 'iostream' file not found
#include <iostream>
^
1 error generated.
I can't find any information on how to configure things to run clang on Windows, and I'm guessing that after I figure out how to tell clang where to search for standard library headers, I'll have to tell it where to look for libraries to link with. Can somebody walk me through the setup step by step or point me to such a walkthrough?
This is a old question, and a lot has changed since then. Given this is a common problem when trying Clang on Windows, it deserves an updated answer.
As of 2017, with the LLVM 3.9.1 build for Windows, you need the following to be able to invoke clang from your shell.
VC++ Build Tools
We still do not have a libc++ port for Windows, so Clang uses the VC++ libraries as well as the VC++ linker.
So first of all you need the VC++ Build Tools on your system. Do note you already have those installed if you happen to have the Visual C++ IDE.
Environment Variables
You need to tell Clang where to find the build tools and its libraries.
Option 1 (vcvarsall.bat)
This is the easiest and standard option.
Run
> "%VS140COMNTOOLS%../../VC/vcvarsall.bat" amd64
Replacing amd64 with your target architecture on Clang, which may be x86, amd64 or arm. You may replace %VS140COMNTOOLS% as well if you have a different version of the VC++ toolset.
As a shortcut, you could run the Visual C++ Command Prompt instead of cmd+vcvarsall, since you need to call this batch for every command prompt you open.
Now you are able to enjoy Clang.
Option 2 (Manually)
In case you cannot run vcvarsall.bat or want to automate this process, welcome, I had the same need.
All of the following environments variables are set automatically by vcvarsall.bat, so you can run that and take your machine values from there. I'll give mines as examples and in the hope it's the same elsewhere.
Set the INCLUDE environment variable to C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE;C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt;C:\Program Files (x86)\Windows Kits\8.1\include\shared;C:\Program Files (x86)\Windows Kits\8.1\include\um;C:\Program Files (x86)\Windows Kits\8.1\include\winrt;
Set LIB to C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64;C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x64;. Do note the architecture specific components!
For the build tools, you can either have the tools on PATH or setup the VCINSTALLDIR environment variable. Clang will try both, favoring VCINSTALLDIR.
Set VCINSTALLDIR to %VS140COMNTOOLS%../../VC or add %VS140COMNTOOLS%../../VC/bin/amd64 to your PATH.
Footnote
This is all very under documented, so the requirements may change at any time, but the Clang MSVC driver is trying to automate this as much as possible, by querying the Windows Register and many other tricks, so none of this may be necessary anymore in the future.
If you are not restricted to use Microsoft compilers. You can use clang with MinGW-w64. Just install the latest version of llvm binary for Windows and MinGW-w64.
You can use the following code to compile your source file
clang++ -target x86_64-pc-windows-gnu test.cc -o test.exe
With Clang for Windows 5.0.0 (64 Bit) (latest versions available here; you want LLVM-x.y.z-win64.exe) and Visual Studio 2017 Community Edition or Build Tools installed in their default setup paths (including the latest/matching Windows SDK):
C:\>clang --version
clang version 5.0.0 (tags/RELEASE_500/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
I've made good experiences using clang-cl (clang-cl.exe == clang.exe --driver-mode=cl) which does find all the necessary msvc library/include dependencies automatically:
C:\>clang-cl hello.cpp
Or to compile as 32 or 64 Bit application:
C:\>clang-cl -m32 hello.cpp
C:\>clang-cl -m64 hello.cpp
Alternative
See Arvid Gerstmann's Blog: Using clang on Windows.
References
How do I tell CMake to use Clang on Windows?
Building a x86 application with CMake, Ninja and Clang on x64 Windows
How do I tell CMake to use Clang on Windows?
Here is what I did to use the clang compiler from the terminal on Windows 10:
I downloaded and installed the Build Tools for Visual Studio 2022. This installs and opens the Visual Studio Installer.
In the Visual Studio Installer I selected three things:
Desktop development with C++ from the Workload tab
C++ Clang Compiler for Windows (13.0.1) from the Individual Components tab.
C++ Clang-cl for v143 build tools (x64/x86) from the Individual Components tab.
Then I added the path to clang.exe and clang++.exe to my PATH environment variable. For me the path was C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\Llvm\x64\bin.
After doing this, I was able to use the clang compiler from the terminal. To compile a C program, go to the source directory and type;
clang *.c
To compile a C++ program, use instead;
clang++ *.cpp
I hope this information is useful to others.