> -----Original Message----- > From: CMake [mailto:cmake-boun...@cmake.org] On Behalf Of Robert > Dailey > Sent: Wednesday, August 05, 2015 19:02 > To: CMake > Subject: [CMake] Managed C++ / C# Projects: Location of assembly DLL > > I am including external MS projects via CMake for my C# projects. The > Managed C++ projects I generate via CMake directly. However, sharing > assembly references between the two is difficult. > > Sometimes I need my imported C# projects to know where to find the > managed C++ DLL assembly it built. This is in the CMake binary directory, > which might be different on each machine, so I can't exactly setup a relative > path to this file in the C# project references section. > > Likewise with dependencies on C# output from Managed C++. It's a little > easier to tell CMake where to find the output DLL file for a C# project (since > the output location is relative inside the source dir). > > How do you guys recommend solving these dependency issues? Is there a > way I can add an assembly reference to a Managed C++ project via path > through CMake?
I also need to use C#. Until CMake has first-class C# support, I hacked together a primitive "csproj" file generator in about a day and a half (excluding the wrong approach I initially took). I also had problems with "how do you deal with references" and "how do you get the C# project to do an out-of-source build?" (I don't want the C# projects touching my source tree, it's not the CMake way.) So initially I investigated calling csc.exe directly as a custom build step but that approach will have two problems: * No IntelliSense support for C# in the IDE because a C++ project is emitted. * More importantly, system references are difficult to resolve. To see what I mean, built a Hello World C# app in Visual Studio and look at the MSBuild invocation to csc.exe. Note they don't specify "/reference:System.Core.dll" on the command line. Instead we end up with a full path to something like "/reference:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" - which is a different path from what is used at runtime (GAC path "C:\WINDOWS\assembly\GAC..."). If you Google there are good reasons to link with the reference assembly and not the one installed on your system. Well it turns out that MSBuild has a complicated set of rules for resolving references, they are not well documented, and they are found in your Microsoft.Common.targets file (search for AssemblySearchPaths to see the list of 9 locations it checks). These rules are different and lengthier than the ones used by csc.exe if an absolute path is not provided. So here's my suggestion: 1. Generate a csproj file on-the-fly from a template and put it into your binary dir, given a list of source files, target name, references, etc. That solves the out-of-source build problem. Make a reusable CMake function(s) for adding C# targets which handles the steps here. 2. Use either include_external_msproject if using a VS generator, or create a custom command/target to directly invoke MSBuild if using a non-VS generator. 3. For references, if you will be using include_external_msproject (as opposed to custom target), and the reference is not an imported target, you will want to generate a project reference. Else, generate a regular reference directly to the file for the configuration. 4. You can use file(GENERATE) to make configuration-specific files that list the references for each configuration. These can then be <Import>'ed into the main csproj file. This lets you use generator expressions if you need to when determining the path for your reference. 5. If generating a project reference to a C++ project, you can use $<TARGET_FILE_DIR:ref>/../ref.vc(x)proj to get to the project file. If the project reference is to another C# project you can use the undocumented EXTERNAL_MSPROJECT target property. If it's a non-project reference then you have to provide a <HintPath> which can be done with $<TARGET_FILE> for C++ references and a custom property you'll have to maintain for C# project references. 6. Don't forget to call CMake add_dependencies() as well. Best regards, James Johnston -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake