Subversion, external references, binaries, and MSBuild/Visual Studio - visual-studio

I have a project that is stored in a Subversion repository.
In this repository, in a different folder, I have a set of libraries that I use in many of my projects. These libraries are stored as binary files, ie. the dll's, pdb's, and xml's.
Here's an example layout:
<repo-url>
\Libraries
\SQLite
\SystemHooks
\Moq
In the application project, I add a "libs" directory, then add a svn:externals reference property to that directory to pull in the libraries I need.
For instance, for this project I am working on now, which prompted this question, I need the SystemHooks library, so in my app project folder structure, it now looks like this:
SketchingMode <-- solution folder, other projects here as well
SketchingMode <-- app project folder
libs
SystemHooks
The nice thing about this is that I can more easily update the libraries, and just use the -rXYZ specifier for the externals definition to avoid pulling in newer versions than I'm ready to accept, and still have only one copy of each file/version in my repository.
The bad thing, in this particular case, is that one of the dll's in the SystemHooks directory (2 if I want the pdb as well) needs to be copied to the output directory, not referenced by the project.
References work as normal, but once I tag one of the files in this directory as "Content" and "Copy always" or "Copy if newer", then the libs and SystemHooks directory structure is also copied to the output directory.
As such, after a build, my on-disk directory structure looks like this:
SketchingMode <-- solution folder, other projects here as well
SketchingMode <-- app project folder
libs
SystemHooks
bin
Debug <-- main build output here
libs
SystemHooks <-- 1-2 files in here
Is the only way to avoid this to use the post-build steps and just add the necessary copy statements? Or can I somehow tweak the project file to avoid copying the full structure like that?
Just to make it clear, in the bin\Debug directory, I don't want another layer of libs\SystemHooks in there, and all the files presently being copied to the bin\Debug\libs\SystemHooks folder needs to be copied to the bin\Debug folder instead.

How about checking out the libs directory to the level of the solution rather than the project? That is what we do since library assemblies tend to be used by multiple projects; placing direct inside one project's directory would not make for a highly shareable resource.
SketchingMode solution
SketchingMode proj
bin
Debug
Release
Libs
SystemHooks

Related

Have Intermediate CMake Files Appear in the IDE

I am developing a system of build scripts for CMake and have an issue with wanting to have intermediate CMakeLists.txt files appear in the IDE for easier search and edit.
I have a main CMake file that includes a directory that includes several subdirectories for libraries.
CMakeLists.txt
--- SubProjects:
-------CMakeLists.txt
-------ProjectAFolder:
----------CMakeLists.txt
-------ProjectBFolder:
----------CMakeLists.txt
-------ProjectCFolder:
----------CMakeLists.txt
In the SubProjects folder, the CMakeLists.txt is very simple and just includes the subproject folders one after the other:
SET(SUBDIRECTORIES ProjectAFolder
ProjectBFolder
ProjectCFolder )
foreach (subdirectory ${SUBDIRECTORIES})
add_subdirectory(${subdirectory})
endforeach ()
However, when I generate this in XCode or Visual Studio, the IDE does not include the intermediate CMakeLists.txt file anywhere because it does not belong to any individual library or executable target. What is the best way to include this somewhere so it appears in an IDE?
Depends on where you want the file to show up, since it doesn't belong to any target. You can simply add it to any existing target (just as you do with source files) or you can create a new custom target.
add_library(AnyExistingTarget <other source files> SubProjects/CMakeLists.txt)
Or create a custom target:
add_custom_target(MyIntermediateCMakeFiles SubProjects/CMakeLists.txt)
For Visual Studio, you could also use the built-in support for cmake. It will display the source tree in the IDE without any extra work.

Keep CLion's project files separately from the project

Is there anyway to keep CLion's project files (i.e. .idea directory) in a separate directory than the project? This feature already exists in IntelliJ IDE but I can't find something similar to CLion...
I'm looking for a structure like this one:
~/my_project/CMakelists.txt
~/my_project/other_source_files
~/project_files/my_project/.idea

Relative paths with MSBuild project vs solution

I have a number of projects which are joined into a solution. Every project has it's own directory structure, and csproj files are located on diferrent level of folder structure.
Every csproj has OutputPath property specified. OutputPath - is a relative path and it varies from project to project in such a way so all projects have the same output dir.
It is work OK if I build a separate project. But everything changes if I try to build solution file. In this case every project output folder differs (depends on a number of '..\' in that project's OutputPath).
I do know, that before some moment all was working fine. Nobody changed build.cmd neither any sln or csproj files. But now I have situation described above.
So my question is - what affects how relative path is evaluated? I mean how can I force relative OutputPath to be evaluated starting from folder where csproj file of that particular project is located. Not from folder where .sln file is.
Let's assume I have following directory structure:
dir1
a.sln
dir2
a.csproj
dir21
dir3
b.csproj
a.csproj has output path set to '../../_bin' which is just above dir1 if counted from a.csproj folder
b.csproj has output path set to '../../../_bin' which is same - just about dir1 if counted from b.csproj
a.sln contains both - a.csproj and b.csproj.
When I run msbuild I get a project build to 'dir1/../../_bin' and b project to 'dir1/../../../_bin' - both relative paths of projects files are counted from solution file location, not project files.
Well, I was able to find out what was causing this. That was custom .targets file, which was inferring SolutionDir property at the start of any msbuild.
I did find out that by using MSBuild Explorer. The tool proved to be very useful in my case - I was not aware of third party .target files on my system.
From Msbuild Import Element description
Relative paths in imported projects are interpreted relative to the
directory of the importing project. Therefore, if a project file is
imported into several project files in different locations, the
relative paths in the imported project file will be interpreted
differently for each imported project.
All MSBuild reserved properties that relate to the project file, for example, MSBuildProjectDirectory
and MSBuildProjectFile, that are referenced in an imported project are
assigned values based on the importing project file.
If you add more details or few samples to your question - it will be easier to understand exact problem.
Edit:
Okay, lets try to pinpoint that mystery. First of all - OutputPath could be affected by Environment variables.
2nd - during build sln file transformed into msbuild project file format and stored in temp file. You can get that temporary file if you execute in cmd "set msbuildemitsolution=1" and then trigger build via command line. There you can check that file and see how your individual projects called. But I suppose you will see multiple .csproj /> entries. And global msbuild properties inherited by that calls.
So I suspect if everything was fine before some point and no changes were made - you are missing OutputPath environment variable or some other variable that contributed to construction of OutputPath.
BTW - I think if you want to fix your issue with forcing relative dir - you also can use $(MSBuildProjectDirectory). This is one of msbuild reserved properties (from here), but this will require yo adjust your OutputPath in each csproj file. What i, personally, prefer to avoid, because it could affect some other targets and introduce subtle issues.

Does "Copy Local" matter if all projects are pointing to the same output folder?

I have a solution of about 50 projects.
I have most of those projects (the non-test ones) setup to output to a single folder.
I have heard that "copy local" can slow down build times (for project references), because it has to copy the file to everywhere it is referenced.
But if every project is copying to the same location is Visual Studio smart enough to see that the file is already there and not copy it again?
So, here is an example:
SolutionA
|
+---ProjectA (Output set to C:\MyProj)
|
+---ProjectB (Output set to C:\MyProj)
| References ProjectA
|
+---ProjectC (Output set to C:\MyProj)
| References ProjectB
|
+---ProjectD (Output set to C:\MyProj)
References ProjectA
In a normal solution, copy local would control the copy of the reference to the bin\Debug folder for each of these projects.
But I have updated the "Output" section of the Project Properties so that they all drop to C:\MyProj instead of bin\Debug.
If I do not set Copy Local to false for references, will ProjectA.dll be copied to C:\MyProj four times? Or is Visual Studio smart enough to only do it once?
I think what you are asking is "does it take any time to copy a file onto itself?" As you might expect, it doesn't. You can see this by using Reflector or ILSpy on the Microsoft.Build.Tasks assembly, the Copy class performs the copy. Its DoCopyIfNecessary() method contains this line of code:
if (string.Compare(sourceFileState.Name, destinationFileState.Name, StringComparison.OrdinalIgnoreCase) != 0)
{
flag = this.DoCopyWithRetries(sourceFileState, destinationFileState, copyFile);
}
Or in other words, it skips the copy if the source and destination file are the same. Necessarily so, File.Copy() won't be happy.
Copy Local copies to the bin directory. Usually Visual Studio will empty this directory on a Clean command. If you don't set Copy Local, you run the risk of not having all your references in the bin folder(s).
You can copy them to the bin folder in another way I suppose; but you'd have to do that manually if you ever run Clean...
As far as I know, VS isn't smart enough to see that each project has the same bin directory, so it would copy four times (test and verify though). In the above scenario you could have only one project with Copy Local and avoid this. But, you'll need at least one with Copy Local otherwise you'll have situations where your bin directories won't have the file otherwise.

Visual studio compile error

I as using visual studio 2010. My solution is having more than one projects in it which are have relationships to each. When I adding a reference to a other project I can use public components (classes,enums ) of that. But when I compile it it gives error saying that those classes are not referenced(Not available).
But when I change the folder structure(When I reduce the level of folder hierarchy/when project folders borings to the root folder ex: d:\ ) it works fine.
Is it because of the length of the folder hierarchi ?
Check your namespaces
When you're adding reference, add it using Project References. So what it does is it compiles the dependencies first. Check if all projects are compiling individually.
Verify target framework versions
No, it is not because of folder hierarchy.... it is because not setting hierarchy properly !!
Follow this steps:
Lets say you have project A and project B.
Project A is dependent on Project B. So we need to add dependency of Project B to Project A.
So right click on Project A -> Open Folder in File Explorer.
Then check which folder it opens into (Lets call it "source folder") and check where the project files whose dependency to be added (Lets call it "destination folder") are located from that folder location. Add the relative path from source to destination folder. (Ex: "..\..\destination folder" ).
Add this relative path in Project A Properties -> Configuration Properties -> C/C++ ->Additional Include Directories.
Good luck.
Yes, hangar18 has suggested correctly. Add reference of each project (Static Libraries) to you execuatble project ( Console Application Project / Startup project).
Also add path of each folder where the header files and corresponding C/C++ files are residing.

Resources