Reputation: 137
In the documentation for Conan, I found this page: https://docs.conan.io/en/latest/howtos/visual_studio_packages.html
This page steps through 2 examples, one is using Conan to generate a .props file to point the Visual Studio IDE to dependencies for your project, and the other is creating a package of a Visual Studio solution/project(s) that has dependencies using Conan. Both of these work for me separately, however combining them to both be able to use VS IDE with Conan dependencies and package the VS solution fails for the following reason:
When using Conan (or the Conan extension for VS) to handle dependencies while using the IDE, the visual studio project files (.vcxproj) are modified to include and import call to the Conan-generated .props files. The project files are source-controlled through Git. Then when calling conan create
on the same conanfile.py, my source
method clones down the repo at the specified tag. This will include project files that are told to import the Conan-generated build files, and then the build
method in conanfile.py will "inject" its own .props file to serve the same purpose. I see two issues here:
Is there some way to have the MSBuild helper (in the build() method of the conanfile.py) use the same .props that would be generated by the conan install
command instead of its own when using a command line arg to msbuild as part of the conan create
command? Or a better solution than that?
I tried to be as clear as possible but please let me know if I can clarify the issue further. Any help is appreciated.
Below is an example conanfile.py trying to accomplish this:
from conans import ConanFile, MSBuild, tools
from conans.tools import load, save
import re, os
class TestConan(ConanFile):
name = "test"
version = "1.1.2"
settings = "os", "compiler", "build_type", "arch"
generators = "visual_studio_multi", "visual_studio"
requires = "snappy/1.1.8", "boost/1.73.0", "rapidjson/1.1.0"
options = {"shared": [True, False]}
default_options = {"shared": True, "boost:shared" : "True", "snappy:shared" : "True"}
def source(self):
git = tools.Git(folder=self.name)
git.clone("http://path/to/test/repo/testrepo.git", branch="1.1.2")
def build(self):
msbuild = MSBuild(self)
msbuild.build("testrepo/testrepo.sln", platforms={"x86":"Win32"}, upgrade_project=False)
def package(self):
self.copy("*.h", dst="include/testrepo", src="testrepo")
self.copy("*.hpp", dst="include/testrepo", src="testrepo")
self.copy("*.lib", dst="lib", keep_path=False)
self.copy("*.dll", dst="bin", keep_path=False)
def package_info(self):
self.cpp_info.libs = ["test"]
self.cpp_info.includedirs = ["include"]
self.cpp_info.bindires = ["bin"]
self.cpp_info.libdirs = ["lib"]
The Visual Studio Project files allow you to conditionally import projects. I adjusted them to only import if the Conan property sheets were found. This made it so that when creating the package using the conanfile.py above, the cloned repo would correctly load for msbuild and then Conan could inject the dependencies accordingly. The Conan extension for Visual Studio doesn't override the conditions so you can still run conan install
and use the IDE for development, then clean the temporary build files (prop sheets) and commit. In my case I just added the .conan folder the extension creates to .gitignore.
Example code for the workaround:
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project=".conan\conanbuildinfo.props" Condition="exists('.conan\conanbuildinfo.props')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project=".conan\conanbuildinfo.props" Condition="exists('.conan\conanbuildinfo.props')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project=".conan\conanbuildinfo.props" Condition="exists('.conan\conanbuildinfo.props')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project=".conan\conanbuildinfo.props" Condition="exists('.conan\conanbuildinfo.props')" />
</ImportGroup>
Warning: I am not a project file xml expert, there might be a better way to accomplish the same as above, but this worked for me.
This is a workaround. What I have found is the examples in the Conan how-tos docs I have at the beginning of this post use "exports_sources" for obtaining their source. It seems that Conan correctly handles this case, but not the case where you instead obtain your source (using the source() method) from SCM, in my case git cloning a specific tag. I tested this with my project repo but for our development flow we prefer the ability to package a tagged git commit.
Upvotes: 1
Views: 3764
Reputation: 13
Take a look at the new "msbuild" generator. I found that it fixes a lot of the issues I was having with this, because it changes the architecture a bit.
At the top-level, it creates a conan_deps.props
file (that could(?) be committed to the repo.
From there, when you perform a conan install
, it creates one "top-level" .props
file per dependency, with individual .props
files below it for each of the configurations.
I've found that this has worked much better for me, as it gave me much more flexibility in my dev environment as well.
The only problem I'm having now is that the VS Extension hasn't 'officially' been updated to support it yet... but I've been getting around that by simply using the embedded Developer Command Prompt for now :)
EDIT (11/4/2020): I actually opened a Github issue in the VS Extension Repository, and the devs got back super quickly! Looks like they are waiting for things to stabilize a bit before making changes to the extension.
Upvotes: 1