Using Specified Lib Version in Vcpkg
Vcpkg is a Microsoft C and C ++ library management solution on the Windows platform. Of course, Vcpkg can also run on Linux and Mac platforms. However, these two platforms already have their own default library system, so I think most developers are unlikely to use vcpkg as their own library management.
On Windows, there is always a lack of a unified Library Manager. We always use case by case way to solve libraries installation. In addition, Windows does not have a unified compilation environment. It is fundamentally different from the way of unix, you can’t use a makefile to complete all the work. In short, everything works unusual. Vcpkg is such an important tool to solve this problem.
Fatal disadvantage: no version management
However, strictly speaking, Vcpkg is not a complete solution. At least I don’t think so. It has a very fatal flaw- there is no function of version management. This shortcoming is very, very serious.
Let me take an example of the problem I have recently encountered: I think that everyone who develops OpenGL or scientific computing will use the two function libraries GLM and GLFW3. In Vcpkg you simply use:
.\vcpkg install glm glfw3
.\vcpkg integrate install
In this way, you can easily use these two libraries directly in your Visual Studio project, and even Header, Includes, Libs can be used without any settings. Visual Studio will be smart enough to help you prepare the necessary DLLs for you based on dependencies. Everything seems so wonderful but one of its huge hidden problems and shortcomings is that, assuming that you have different projects that need to use different versions of the libraries. Sorry!!! Vcpkg does not have the function of multiple version management. At this time you cannot use “One” Vcpkg to meet all your needs.
Vcpkg a solution based on GIT version control
In order to find a solution, we must first understand how Vcpkg works. Vcpkg is a set of GIT based library management tools. It is more like that Microsoft manages a set of cloud library versions for you. What it cares about is not which version of the function library you want. Instead, Microsoft has been evolving these versions for its own way. He only cares whether they can work properly, not whether you can work normally. So once git pull then you may unwittingly update the version of a bunch of libraries to another version. As a result, your project may no longer work properly.
Any synchronization and update of Vcpkg will bring a lot of conflicts and problems. Maintaining a specific set of Vcpkg is important to ensure the normal operation of the project.
Solution 1: Use multiple Vcpkg
Since updating Vcpkg may cause potential problems, maintaining a specific version for specific projects will also reduce problems caused by conflicting versions. And this will not bring extra work, just waste more disk space.
Because Vcpkg is based on GIT. Therefore, we can understand which Vcpkg is best for us by observing GIT Log. Take OpenSSL as an example:
My project needs to use OpenSSL 1.0.2s version. But the head version of Vcpkg is OpenSSL 1.1.1, so I cannot use the head version on the master. The easiest way is to use a specific Tag directly. Because the version of Tag is mostly stable. As a result, I have an proprietary Vcpkg in my project.
.\vcpkg integrate project
Open Package Manager Console:
Visual Studio -> Menu -> Other Windows -> Package Manager Console
Install the nupkg installation path generated by Vcpkg :
Install-Package vcpkg.C.vcpkg -Source "path\vcpkg\scripts\buildsystems"
After installation, your Visual Studio can automatically reference and compile these libraries. Very convenient. And no manual setting is required.
Please note that you can only use one nupkg generated by Vcpkg at the same time. Only one Vcpkg nupkg is valid. Of course, your installed nupkg owns the higher priority, you don’t have to worry about other Vcpkg. In other words, other Vcpkg integrate install will not affect your project. This point is very important.
Solution 2: Use independent nupkg installation package
You may notice that if all project uses the full Vcpkg, they will consume lots of disk space. For example, a C ++ Boost may have up to 10GB of space. You may only need a few small tools from the Boost library, but you have to pay a lot of space, which is really not good idea.
Fortunately, we can package the Vcpkg installed in Solution 1 into an independent installation package. In this way, we only need to refer to this installation package in the project to avoid re-downloading and compiling the entire Vcpkg.
Pack the nupkg installation package:
.\vcpkg export boost boost:x64-windows zlib --nuget
In this way, we have a name: vcpkg-export-20200417–005338.nupkg. And it only requires about 250MB of space. Next, we only need to distribute this installation package to all projects that need these libraries, and we can easily solve the problem of installing the libraries.
For example, we may check out a new project and then we just install this standalone nupkg file.
Install-Package vcpkg-export-20200417-005338 -Source "path of nupkg"
Note that installing packages in this way also cannot support multiple Vcpkg nupkg. It will also be affected by root Vcpkg integrate so that please remember to remove the integrated installation of root Vcpkg before compiling. Use root .\vcpkg integrate remove.
Vcpkg is undoubtedly a powerful library management tool. But the lack of version management caused a lot of trouble. In fact, the multiple Vcpkg method can only solve part of the problem of multiple versions. For more complex versions, manual adjustments must be used. It is difficult to say whether it is worth it. In addition, Vcpkg fully supports the CMake function, which is also very important. Because there is no default library path in the Windows environment, for multiple CMake, find_package is needed, and it is almost impossible to find the corresponding package correctly. Using the CMake toolchain to set to Vcpkg has become a super convenient solution.