I need to build the Windows library targetting the MS VC Runtime 12.0 (the one that came out with VS2013, which maps to MSVCR120.dll), but in the latest dev 0.7.0 branch, there is only two projects left: one for Visual Studio 2008 and one for Visual Studio 2010 (targetting MSVCR100.dll). The project for VS2013 is gone. I'm not sure how to use the CMake stuff, but after a quick look, it does not seem to have code that specifically deal with the version of the VC runtime in it.
Usually, each developper will use version X of Visual Studio (2010, 2013, 2015, 15/vNext, ....), while targetting a version Y of the Microsoft VC Runtime (10.0, 11.0, 12.0, 14.0, ..., with Y <= X). I guess most dev may use a more recent version of VS than the version of the runtime they target, because retargetting all your dependencies to the latest VC runtime can be a lot of work, or even not possible at all. This means that the version of the VC runtime may not be the same as the version of Visual Studio project, and will be different for each person.
Currently, if you have VS 2015 Update 2, and open the VS2010 project in the dev branch, VS attempts to convert the project to the latest version possible (14.0, which will probably break because of some includes that are different). And if you don't perform the conversion, then the build will probably fail because you don't have the 10.0 SDK installed on your dev machine or CI build server (unless you have also installed VS2010 before). Plus, if you want a different version (12.0 for me), you then need to update each project (for all the projects, times two for Release/Debug, times two again for Win32/x64). And then you are left with a change in the .vcproj that will cause trouble when you update from git again (forcing you to maintain a custom branch).
I can see that having to maitain one set of projects for each versions of Visual Studio can be too much work, but what do you think would be the best way to be able to specify which version of the VC runtime to target when building? Maybe a settings for CMake that would then create a set of VS projects specific to you, and not checked in the repo? (this would be ideal).
To be more precise, I'm talking about the PlatformToolset field in the .vcxproj, which I had to add to all configurations of all projects.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset> // <-- this field was added when selecting the target platform in VS.
</PropertyGroup>
The current project does not have this field, which defaults to the v100 I think (probably the version of msbuild targetted by the project itself).
The full patch on a project after conversion+config looks like:
diff --git a/projects/VS2010/zstd/zstd.vcxproj b/projects/VS2010/zstd/zstd.vcxproj
index 40cb20d..290f7fb 100644
--- a/projects/VS2010/zstd/zstd.vcxproj
+++ b/projects/VS2010/zstd/zstd.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@@ -77,29 +77,34 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>zstd</RootNamespace>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
This is indeed an issue.
The VC2010 project was created on the ground that it should prove upgradable by any newer version of Visual Studio. This hypothesis was not thoroughly tested, but seemed to work fine on the few test cases we could create.
For example, I currently use Visual 2015 community edition (Update 2), since I recently switched laptop and lost my Visual 2013 Pro license.
Method : copy the project into another directory (to avoid conflict with git), open solution, accept project updates, compile. run. So far, it has worked fine.
I would expect the experience to be reasonably similar on intermediate versions (2012 and 2013), though I haven't tested it and maybe I should.
Now if I try something more complex, such as updating to VC runtime v120 of Visual 2013 from within Visual 2015 _after_ having converted it first to v140 Visual 2015, then it fails and complain about some missing LIBCMT.lib.
Now, if I initially _don't upgrade_ the project, Visual 2015 cannot compile it as is, since it doesn't have the v100 platform runtime. But then if I ask for the Visual 2013 runtime (v120), it compile and run fines.
So, the current expectation is that the project should be automatically and correctly upgraded by the version of Visual which opens it. If it does not, this is a limitation, and we should try to do something about it.
Coming back to your case, since you are looking for the v110 runtime from Visual 2012, does that sound an acceptable process to update it to the runtime you want by first opening it with Visual 2012 (express), and later be able to open it with any other version >= 2012 for any future work or compilation ?
Actually, I need v120 runtime (VS2013), but I think the issue is that the version of Visual Studio may or may not be correlated to the version of the VC runtime you want, plus the fact that migrations will cause you to either have to maintain a custom branch, OR if you copy the projects to a different folder, then updating the source from git later will not update your copy of the project, causing problems...
Another thought: if you are maintaining multiple version of your application, you may need to build targetting v110 for version N-1, and v120 for version N. Plus you are probably already working on vNext where you decided to retarget to v140 or something else.
And, because this is not complicated enough, there are also the v120 and v120_xp variants of the VC Runtime :scream:
If you are going to use CMake, then maybe this could be solved by having two parameters: what version of VS do you need (what you have installed on your machine) and what version of the VC runtime are you targetting, and have it generate or regenerate your projects. That way you will not need to modifiy anything in the project, and will be able to regenerate them after pulling from the git repo.
You could then have your CI build server run CMake as part of the build with settings corresponding to what branch of your app you are building, and things would work fine...
To sum up:
If you have VS2015 but want to target v120 (or v110 or v120_xp or whatever), the current story is to open the VS2010 project, have VS prompt you to upgrade the project (to v140 which is not what you want), but cancel the upgrade. You end up with an unbuildable project that targets v100 which is not installed on your box (probably). Then, edit the properties of all 5 projects, select All Configurations/All Platforms in the General tab, and change Platform toolset to Visual Studio 2013 (v120). Then if you are lucky it will build fine, or else you may need to fiddle with the include paths, or add some libs (usually the build error message will be explicit enough, or google will help you)
Then you end up with pending changes in the .vcxproj files which will always conflict when pulling/merging from the github repo.
If I had VS2013, it would be different: I could let it convert my project because it would select v120 which is what I want. But if I had targetted v110 I would be back to the case above.
I have VS 2012 Express and VS 2015 Community. To compile zstd using /projects/VS2010: I open VS 2012 then I open the zstd project and I click "Update" and "Build". The same with VS 2015, but at the beginning I open VS 2015.
The second option one may use is MSBuild. It works fine with Travis:
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build
Cmake.exe allows to select Visual Studio version. It only generates CMakeFiles.txt if given version of VS is installed (works fine for me as well):
Visual Studio 14 2015 [arch] = Generates Visual Studio 2015 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 12 2013 [arch] = Generates Visual Studio 2013 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 11 2012 [arch] = Generates Visual Studio 2012 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 10 2010 [arch] = Generates Visual Studio 2010 project files.
Optional [arch] can be "Win64" or "IA64".
Visual Studio 9 2008 [arch] = Generates Visual Studio 2008 project files.
Optional [arch] can be "Win64" or "IA64".
Visual Studio 8 2005 [arch] = Generates Visual Studio 2005 project files.
Optional [arch] can be "Win64".
Visual Studio 7 .NET 2003 = Generates Visual Studio .NET 2003 project
files.
Visual Studio 7 = Deprecated. Generates Visual Studio .NET
2002 project files.
Visual Studio 6 = Deprecated. Generates Visual Studio 6 project files.
Yes, indeed @KrzysFR .
This method works to update projects to v120 runtime (Visual 2013) using Visual Studio 2015.
The experience would likely be less frustrating if using Visual 2013 to upgrade to Visual 2013 runtime.
Using a compiler version with a different runtime than default has always been awkward with Visual GUI.
Maybe the msbuild solution proposed by @inikep proves a better choice.
_Edit_ : just tested to be sure : downloaded Visual 2013 express, copied zstd solution, open, select "upgrade projects", compile, run. It worked flawlessly.
_Conclusion_ : upgrade to same runtime as compiler version seems to work fine.
So, the complexity comes when trying to convert into a different runtime than compiler's default.
I've seen cases where you have multiple build.VS2013.cmd, build.VS2015.cmd files in the repo (choose your own) that invoke msbuild or other (see https://github.com/gitextensions/gitextensions/tree/master/Build or https://github.com/gitextensions/gitextensions/tree/master/Setup) but this may not solve the issue of the platform toolset, unless you provide a .cmd for each subset of (VS_version x Toolset_version). But at least you can easily create your own .cmd file and use it.
Also, when I only want to build the library, and I'm not working on zstd itself, having a .cmd that builds the proper version for me seems better than having to open the project in VS and fiddle with it.
The experience would likely be less frustrating if using Visual 2013 to upgrade to Visual 2013 runtime.
Indeed, and we do have an MSDN subscription so could install multiple version of VS on our machines and build server if required.
But I suspect a lot of people will use the free Visual Studio 2015 Community Edition (https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx) to tinker with zstd, and may end up with projects automatically migrated to v140.
(for all the projects, times two for Release/Debug, times two again for Win32/x64)
True for all the projects (5 now), but you may use "All Platforms" and "All Configuration".
MSBuild 14 works with all platforms (tested VS 2008 and newer). There was only one problem with Travis: compilation with VS 2010 x64. It was solved by:
SET ADDITIONALPARAM=/p:LibraryPath="C:\Program Files\Microsoft SDKs\Windows\v7.1\lib\x64;c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64;C:\Program Files (x86)\Microsoft Visual Studio 10.0\;C:\Program Files (x86)\Microsoft Visual Studio 10.0\lib\amd64;"
The whole script is:
ECHO *** Building Visual Studio 2008 %PLATFORM%\%CONFIGURATION% &&
ECHO *** &&
msbuild "projects\VS2008\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v90 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
ECHO *** &&
ECHO *** Building Visual Studio 2010 %PLATFORM%\%CONFIGURATION% &&
ECHO *** &&
msbuild "projects\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
ECHO *** &&
ECHO *** Building Visual Studio 2012 %PLATFORM%\%CONFIGURATION% &&
ECHO *** &&
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
ECHO *** &&
ECHO *** Building Visual Studio 2013 %PLATFORM%\%CONFIGURATION% &&
ECHO *** &&
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
ECHO *** &&
ECHO *** Building Visual Studio 2015 %PLATFORM%\%CONFIGURATION% &&
ECHO *** &&
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
Ok so taking a look at how the gitextensions project does things, I've tried doing the following:
Have a folder build in which I have an all-purpose build.generic.cmd script that can take all the required params (vs version, release/debug, x64/win32, msvcrt version, ....). Then have build.VS2013.cmd or build.VS2015.cmd helper batches for the most common case (you have VS2015 and don't care, run this).
build.generic.cmd
@echo off
rem
rem Parameters
rem %1: vs_solution_version: VS solution version: VS2012, VS2013, VS2015
rem %2: vs_configuration: VS configuration: Debug, Release
rem %3: vs_target: target: Build or Rebuild
rem %4: vs_platform: platform: x64 or Win32
rem %5: vs_toolset: toolset: v100, v110, v120, v140
rem
set vs_solution_version=%1
set vs_configuration=%2
set vs_target=%3
set vs_platform=%4
set vs_toolset=%5
set msbuild="%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe"
IF %vs_solution_version% == VS2013 SET msbuild="C:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe"
IF %vs_solution_version% == VS2015 SET msbuild="C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"
set project="%~p0%..\projects\VS2010\zstd.sln"
set output="%~p0%bin\%vs_solution_version%\%vs_platform%"
set msbuildparams=/verbosity:minimal /p:Platform="%vs_platform%" /p:Configuration="%vs_configuration%" /p:PlatformToolset="%vs_toolset%" /t:Clean,Build /nologo /p:OutputPath=%output%
echo ### Building %vs_solution_version% project for %vs_configuration% %vs_platform% (%vs_toolset%)...
echo ### Build Params: %msbuildparams%
%msbuild% %project% %msbuildparams%
IF ERRORLEVEL 1 EXIT /B 1
echo # Done
echo #
build.VS2013.cmd
@echo off
rem build 32-bit
call "%~p0\build.generic.cmd" VS2013 Release "Clean,Build" Win32 v120
rem build 64-bit
call "%~p0\build.generic.cmd" VS2013 Release "Clean,Build" x64 v120
build.VS2015.cmd
@echo off
rem build 32-bit
call "%~p0\build.generic.cmd" VS2015 Release "Clean,Build" Win32 v140
rem build 64-bit
call "%~p0\build.generic.cmd" VS2015 Release "Clean,Build" x64 v140
(cmds for VS2010 and VS2012 would be very similar).
Both cmd work on my machine, but I have VS2013 and VS2015 installed.
People who have the VS2015 Community Edition and just want to tinker with zstd out of the box can simply run the build.VS2015.cmd script and have both x86 and x64 version build for release, and start running benchmarks.
People who want very fine grained settings, can invoke build.generic.cmd directly with the proper settings (you just need to open one of the build.VSXXX.cmd to see what are the possible settings, and it would not take a genious to know to change v140 into v120)
The only thing I did not copy from the gitextension project, is that they have multiple project files, one for each version of VS, and the build.generic.cmd script build the path to the correct project depending on the target version of VS. Right now, I'm always building the VS2010 project, only changing the path to msbuild (depends on the version of VS installed) and the platform toolset (which must be installed).
One thing I tried to do, but does not work, is changing the output path for the build to something else, but msbuild seems to ignore the argument, and builds inside the project/VS2010/.. subfolder. Anybody has an idea?
Try /property:OutDir="C:\path\to\binaries"
Yes, that plus some other hacks fixed the issue, so now build.generic.cmdlooks like this:
@echo off
rem
rem Parameters
rem %1: vs_solution_version: VS solution version: VS2012, VS2013, VS2015
rem %2: vs_configuration: VS configuration: Debug, Release
rem %3: vs_target: target: Build or Rebuild
rem %4: vs_platform: platform: x64 or Win32
rem %5: vs_toolset: toolset: v100, v110, v120, v140
rem
set vs_solution_version=%1
set vs_configuration=%2
set vs_target=%3
set vs_platform=%4
set vs_toolset=%5
set msbuild="%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe"
IF %vs_solution_version% == VS2013 SET msbuild="C:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe"
IF %vs_solution_version% == VS2015 SET msbuild="C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"
set project="%~p0\..\projects\VS2010\zstd.sln"
set output=%~p0%bin
set output="%output%/%vs_solution_version%/%vs_platform%/"
set msbuildparams=/verbosity:minimal /p:Platform="%vs_platform%" /p:Configuration="%vs_configuration%" /p:PlatformToolset="%vs_toolset%" /t:Clean,Build /nologo /p:OutDir=%output%
echo ### Building %vs_solution_version% project for %vs_configuration% %vs_platform% (%vs_toolset%)...
echo ### Build Params: %msbuildparams%
%msbuild% %project% %msbuildparams%
IF ERRORLEVEL 1 EXIT /B 1
echo # Done
echo #
Running build.VS2015.cmd from the build folder, on a machine with VS2015, would compile everything for both x86 and x64 in build/bin/VS2015/Win32/ and build/bin/VS2015/Win32/x64. Likewise for build.VS2013.cmd. I don't have VS2010 or VS2012 installed, but probably the build.VS2010.cmd and build.VS2012.cmd could be created the same way.
And if someone would want something custom, invoking build.generic.cmd with custom settings would work.
Do you think this would be an acceptable solution? I could create a PR for this.
Ok, there is something weird. After testing the various scripts using different toolset platforms (v100, v120, ...), and opening the resulting dll with Dependency Walker, I don't see any reference to any version of msvcrt anymore. The only direct dependency are kernel32.dll, and advapi32.dll (only for zstd.exe).
Did something change?
The whole issue resolves around the fact that, before, the dll required MSVCRT, and so needed to be build to a specific version (the one installed on the host or deployed alongside the app). But if zstd does not depend on mscvrt anymore, then it makes things a lot simpler !
AFAIR I have changed compilation to static. The executables are bigger but work with all Windows even without MSVC runtime.
Do you think this would be an acceptable solution? I could create a PR for this.
Yes, I believe it would be a great addition
AFAIR I have changed compilation to static. The executables are bigger but work with all Windows even without MSVC runtime.
Oh so that explains why the size of the dll doubled, and the .pdb went from 300k to 1.3 MB !
Is this a good thing? How would a statically compiled version of zstd targetting MSVC100.dll (for example) cohabit with another library dynamically compiled with another version?
Also, this means that if there is a critical bug in MSVCRT you cannot fix it by updating the version installed on the host, and would need to update zstdlib itself...
Is this a good thing? How would a statically compiled version of zstd targetting MSVC100.dll
cohabit with another library dynamically compiled with another version?
I don't see any problem.
For executables like zstd.exe and fullbench.exe is better to be statically linked because of portability (most non-developer computers don't have MSVC runtime installed). We do the same for Linux.
For zstdlib is not so easy. OK, you have auto fixes (Windows Update) when a bug in MSVC100.dll is found. This can be a problem for VS 2015 but how often does it happen for old versions of MSVC (after VS Service Packs)? It also adds requirement of having MSVC runtime installed. In case if it's not installed user has to dowload many MB of runtime only for this program.
I checked and all projects are:
If you prefer dynamic linking you can always change project properties (C/C++ -> Code Generation -> Runtime Library) or use compilation option "/MD" instead of current "/MT".
I agree with you for zstd.exe, which sould be as standalone as possible and not require any other file or dependency installed.
This can be a problem for VS 2015 but how often does it happen for old versions of MSVC (after VS Service Packs)?
For zstdlib, when targetting MSVC100.dll you are right, there won't probably be any updates to it I guess, but that may not be the case if you target MSVC120.dll or MSVC140.dll which should still be supported for a while.
I don't have a strong opinion on static vs dynamically linked. You just need to remember that your version of zstdlib was build against version FOO of MSCVRT, and maybe remember to manually update it, if you hear about some bug or possible exploit that has been patched by Microsoft in version BAR (which would have been pushed to all your customers server as part of Windows Update).
It also adds requirement of having MSVC runtime installed. In case if it's not installed user has to dowload many MB of runtime only for this program.
Again, true for zstd.exe which will probably be deployed as a single file (or stored in a network share or usb key)
But for zstdlib, it will probably be deployed as part of an application, not as a single standalone file. This application will also depend on a specific version of MSCVRT (for example, ours targets v120), and you will need to deploy it as part of your setup.
My only remaining question is if there are any known issues in having libFOO.dll statically linked against MSCVR100.dll, and libBAR.dll dynamically linked against MSCVR120.dll, both running at the same time in the same process. I don't think so, but again I have never tested this scenario.
If this is perfectly fine, then if zstdlib is statically linked with a specific version of MSCVR, I guess we can simplify the build scripts by only dealing with the dimension of the version of Visual Studio installed, and assume that it will build with the version of MSCVRT that was installed with it.
This means that I only need to write one build script per version of VS, using the version of msbuild that corresponds to it.
I created a PR for this, see #202.
With #202 merged, and since the library is statically linked with MSVCRT, the only remaining issue is having an easy way to build a VS2010 project (the one in the repository) on a machine that has another version of VS installed.
The build scripts added in #202 helps the scenario of a casual user of zstd that only wants to quickly build zstd.exe or the library, and play with it. He or she can use the appropriate build.VSxxx.cmd alias (according to what he or she has installed). More advanced users can also pass custom settings to build.generic.cmd.
For people who want to tinker with the code of zstd itself, when they open the 2010 project with a more recent version of VS , they will be prompted to upgrade to the latest toolset, which may or may not work, and require fiddling with the project settings. This could be solved by having CMake create project files for each version of VS. But then they will end up working on a copy of the .vcproj that will not be upgraded when things change in the repo (files added/renamed/removed).
Not sure how you want to handle that scenario, but this seems out of scope of the current issue (version of MSVCRT).
Likewise, the issue of dynamically vs statically linked could be debated in another thread, for people who care about it. If needed, the generic build script could have another parameter to select static vs dynamic ?
If needed, the generic build script could have another parameter to select
staticvsdynamic?
Yes, it's probably a good place for it.
Shouldn't *.cmd be in "projects/" instead of "build/"?
I would personally probably look into a "build" folder to find scripts to build the projects.
The parameter "vs_version" doesn't make sense. It only selects msbuild (which may not be available). It should be called msbuild_version
Copied from the GitExtensions scripts. Originally, they also use it to select the corresponding VS20XX.sln/.proj files to build (not only msbuild). If we have only one VS .sln file, then indeed the variable only specify the version of msbuild selected, and could be renamed...
The following path will work only with 64-bit Windows: "C:\Program Files (x86)\MSBuild14.0\Bin\MSBuild.exe". In 32-bit Windows it should be "C:\Program Files\MSBuild14.0\Bin\MSBuild.exe". [...] The above issues can be fixed with using "%ProgramFiles(x86)%" for x64 and "%ProgramFiles%" for x86.
Yes indeed. I did not notice the hard-coded program files path when updating the script.
Does anyone still develop on a 32-bit Windows machine, though? If that's the case, the build script should also probably not attempt to build the 64-bit version of zstd, since it will probably not work ?
Moreover in many languages it's not called "Program Files" at all
(http://www.samlogic.net/articles/program-files-folder-different-languages.htm)
I'm very familiar with this issue, since my OS use the french locale. Though this is only a display issue by explorer. Even though it will show "Utilisateurs" or "Programmes" (instead of "Users" or "Program Files"), the actual path of the files will still be "C:\Users..." or "C:\Program Files...".
I've always found it stupid that explorer only localizes some folders and not all... It can be disabled through the registry or Desktop.ini.
Either way, scripts should always use env variables to get the path to the various special folders on windows.
Made some changes in #207 to fix the hard-coded path issues, as well as renamed all vs_ variables to msbuild_
I can now easily build the project targeting whatever version of the Platform Toolset I need, so for me this issue can be closed, unless there are some more changes required.
It would be nice if someone could contribute the various build.{UNIX_FLAVOR}.sh scripts for the linux and BSD's out there, to help those of us that are not familiar with these platforms, but still need to build it quickly :)
Here is are a few command lines that anyone can use, for reference:
If you only have Visual Studio 2013 installed (msbuild v12.0):
Running the following command will build both the Release Win32 and Release x64 versions:
build\build.VS2013.cmd
The result of each build will be in the corresponding build\bin\Release\{ARCH}\ folder.
If you only need one architecture:
build\build.generic.cmd VS2013 Win32 Release v120build\build.generic.cmd VS2013 x64 Release v120If you want a Debug build:
build\build.generic.cmd VS2013 Win32 Debug v120build\build.generic.cmd VS2013 x64 Debug v120If you only have Visual Studio 2015 installed (msbuild v14.0):
Running the following command will build both the Release Win32 and Release x64 versions:
build\build.VS2015.cmd
The result of each build will be in the corresponding build\bin\Release\{ARCH}\ folder.
If you only need one architecture:
build\build.generic.cmd VS2015 Win32 Release v140build\build.generic.cmd VS2015 x64 Release v140If you want a Debug build:
build\build.generic.cmd VS2015 Win32 Debug v140build\build.generic.cmd VS2015 x64 Debug v140The build for v14.0 of the MSVC runtime is larger than 12.0, so if you wan't to reduce the size, you can target the previous toolset version
You need to invoke build\build.generic.cmd with the proper arguments:
For Win32
build\build.generic.cmd VS2015 Win32 Release v120
The result of the build will be in the build\bin\Release\Win32\ folder.
For x64
build\build.generic.cmd VS2015 x64 Release v120
The result of the build will be in the build\bin\Release\x64\ folder.
If you want Debug builds, replace Release with Debug.
Thanks for a great contribution @KrzysFR !
I believe these explanations could make a great README.md in the build folder
Just added your comment in a README.md file in the build directory.
Also : I initially expected this build directory to be located within project, and did not notice it was not.
Does that cause any concern to move it there ?
(seems that one variable in one file must be changed, which is a pretty small modification)
I'm used to having 'build' folder at the root of the repository, but if you want it under 'project' I don't really care.
Why not having the scripts in the project folder itself? at least they can be discovered in one click from the repo root, instead of having to explore two levels of subfolders?
That doesn't "feel" right, since the point is to have multiple build systems within "project" directory.
Though the scripts could be merged within "VS2010" directory, since they use it.
But that doesn't address the "single-click from root" concern.