I'm evaluating TFS Build 2013 for use in a corporate environment.
TFs itself has been running fine for ages, and today I setup the Build components. No problem so far.
I grabbed a fairly simple project from source and created a manually triggered build definition, using the standard defaults.
I ran a test build and hit an issue straight away with a primary reference. The error in the logs is:
C:\Program Files (x86)\MSBuild\12.0\bin\amd64\Microsoft.Common.CurrentVersion.targets(1697,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "XYZ.dll".
So a bit of back of background on how we store and use references:
We create a root folder for the solution, inside this goes the .sln file and sub directories for the projects as normal. We then add a "References" folder at this level, which holds all of the DLLs required for the project. These are generally DLLs from other in house code libraries, but also certain 3rd party ones (such as the old Enterprise Library DLLs, and anything else we don't get from NuGet).
Each of the projects that require these DLLs reference this folder (and from inspecting the .proj files I can see the link is stored as "..\References\XYZ.dll" etc. This works fine for local builds and nobody has ever had an issue. The reference folder gets checked into TFS and everybody gets a copy. From what I've read through trying to diagnose our issue, this is a fairly common and accepted way to manage references.
So, the build error that I receive is as above. Basically saying the build target can't find the DLL from the References folder. The log goes on to list all of the places it's tried to find it.
Crucially (it would seem) the first line reads:
For SearchPath "{HintPathFromItem}".
Considered "..\References\XYZ.dll", but it didn't exist.
Furthermore it looks in the Framework folder, various default assembly folders, the GAC and so on, none of which (of course) contains it.
So I'm wondering where I've gone wrong. Have I misconfigured one of the build/drop locations? Is there some other convention for referencing required DLLs (bearing in mind our entire company uses the "..\References" folder setup, or is there something else?
I'm fairly new to TFS Build, but I'm by no means new to TFS or Visual Studio
itself. I've spent about an hour or so Googling without finding anyone experiencing the same issue as me, so any help would be greatly appreciated.
Thanks
UPDATE:
The build agent is configured as follows:
Build Agent- working directory:
D:\BuildAgent\$(BuildAgentId)\$(BuildDefinitionPath)
The build definition "Source Settings" have the (I assume) default values of:
Status: Active | Source Control Folder: $/ProjectRoot | Build Agent Folder: $(SourceDir)
Status: Cloaked | Source Control Folder: $/ProjectRoot/Drops | Build Agent Folder:
The references folder is not explicitly configured here, but when I look in the Build Agent's working directory I can see it:
D:\BuildAgent\1\ClientName\SolutionName\src\Dev\Evolution\Source\SolutionName.Solution\References
If I open VS2013 Command Prompt, navigate to the folder that contains the .sln file (and also the References folder) and run "msbuild d:\path\to\Solution.sln" then it builds successfully with no warnings or errors.
Well it turns out this wasn't a fault with TFS at all...
The problematic DLL, although present in the References folder, was not actually checked into TFS.
Right clicking the References folder in VS (added as a "Solution Folder") and selecting to Add Existing Item, then a check in fixed the issue.
So the References folder was being used as you would expect, in the same way that VS uses it. MSBuild worked locally because I had the file in my local folder, but because it wasn't part of the solution it wasn't with the rest of the source.
Related
I have made a new build definition. Most options are kept on default. I'm just playing around for the moment.
Problem is that when I build my projects as release mode in Visual Studio 2013 all is good, not errors. When TFS builds it I have a few errors:
(I had to translate it from my own language to English, sorry for that)
TemplateService.cs (80): Core.Infrastructure.Objects.PredefinedTemplate does not contain a definition for TemplateId and there is no extentionmethod TemplateId found gevonden *(something with first argument)* of the type Infrastructure.Objects.PredefinedTemplate is being accepted (possibly missing a user instruction or an assmbly-reference)
The things I already did:
Set the copy local of the referenced DLLs to false and true again, as stated on some websites
Check the build definition if it cleans the workspace (it does)
Added assembly names to the objects in code. I.e.:
PredifinedTemplate to Core.Infrastructure.Objects.PredefinedTemplate
Whatever I do, I keep gettings these errors! Does anyone know what is happening?
UPDATE:
As stated by James Reed I have placed the referenced projects in NuGet packages. In the end I had to place two projects in NuGet-packages. The build on TFS works now and it even deploys to the server.
Using NuGet is not my first choice, because of debugging functionality. But for these two projects, that only holds objects and data-entities, it should not be a problem.
You are missing an assembly reference. i.e. the dll containing the definition for TemplateId is not available on the build server.
If this is defined in a project in the same solution, then something is wrong with the project reference, try deleting and recreating the reference.
If this is a binary reference then you have 3 options
Add the project to the solution and use a project reference.
Check the binary in to source control (not recommended)
Use nuget to manage your references
I'm working on C++\CLI that someone else started. The solution is made up of 3 C projects and 1 C++\CLI project that uses them.
I've duplicated the C++\CLI project and change it name and ProjectGUID property in the vcxproj file.
The problem is I still get the error listed bellow.
How can I fix this?
Warning 1 warning MSB8028: The intermediate directory (Debug\) contains files shared from another project (my_project.vcxproj). This can lead to incorrect clean and rebuild behavior. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets 388 5 seebo_prod_line_tool
Same problem here, solved by
Deleting all Debug\ and Release\ folders (there were more of them in subfolders where I didn't expect them)
Changing the .sln file manually to fix the name of a referenced C++ project (.vcxproj) which apparently was not renamed when renaming the project in Visual Studio
My suggestion is to make sure the intermediate directory for each project is different (as suggested by someone else earlier.)
To do this,
Open the project's Properties dialog
Under Configuration Properties, select General
Make sure the Intermediate Directory for this project is unique to this project.
I ran into this problem because using previous versions of Developer Studio I had a host of companion projects but wanted all of them to put their output in a common "Release" folder. Inadvertently I had set the same common release folder settings in the Intermediate Directory path for some of the projects (but not all).
I found you can disable these types of warnings by added the following to the project file:
<PropertyGroup>
<IntDirSharingDetected>
None
</IntDirSharingDetected>
</PropertyGroup>
I myself also encountered this kind of warning.. But I obtained this in a different situation, I renamed my whole solution/project via IDE and thus making another copy of an entirely different project. So what I have here is a total of two projects sharing one common resource, source and header files. This makes this warning pop up.
I fixed this by deleting the files associated with the project, which you renamed previously. Delete these INSIDE the DEBUG folder. In your case, try deleting all 'my_project' files, regardless of any file extensions because it shares resource files to your duplicated project.
The cause of this problem is copying an intermediate directory that was created by Visual Studio, and that already contains files from a previous build. It is not a problem in the project settings, but a problem caused by the existence of unexpected files from another project. In this context the warning is benign, but annoying.
The minimal solution is to find and delete each such file. The simpler solution is usually to "super clean": delete every directory created by Visual Studio (with names like bin, obj, x64, x86, Debug, Release and so on), and allow VS to re-create them during the normal build process.
I have experienced this problem as well, and for me, the cause was that there were multiple libname.tlog directories inside the intermediate build folder. These directories contain libname.lastbuildstate files that I assume are used for dependency checking. Doing a Clean of the project I don't think will delete these extra directories.
So in this case I was able to delete the libname.tlog directories and build again. I don't know how it got into the state of having multiple directories inside each intermediate directory -- perhaps they were created when I updated the VS version.
I've got a TFS project with a NuGet package installed, and it references an assembly from that package. However, another copy of the same file is in a folder in the tree, and it is somehow overriding the reference and being used instead.
Even if I remove the reference entirely and manually point it to the correct path, the other file still is recognized and overrides the path.
Actual Case:
Correct Reference Path:
c:\Stratigen\Stratigen\packages\MonoGame.Binaries.3.2.0\build\net40\MonoGame.Framework.dll
Overriding Reference Path:
c:\Stratigen\Stratigen\Stratigen\Tools\MonoGame.Framework.dll
The file in "Tools" needs to be there because it is a build against SharpDX (API wrapper for DirectX) and is used to compile shaders for multiple versions of MonoGame, while the game should be running against the OpenGL version (unless I were to purposefully change something).
The especially odd thing about this is that I've had this file in the "Tools" folder this entire time, and for weeks never encountered this issue, yet now it's got this odd behavior.
It seems that having included the "Tools" directory in the project was to blame. This folder is already handled by TFS but since there are a few source files in there (for the shaders) I'd included the folder. However, this for some reason gave priority to the DLLs there over those from the packages. I'm going to re-add the source files but not the DLLs/EXEs from that folder and it should work fine then.
I have read this post thoroughly: How does Visual Studio's source control integration work with Perforce? and found it very informative. However, I have a specific issue that is blocking my use of Perforce in VS.
For the most part, I have no complaints about the plug-in (I'm still using the P4VSCC plug-in because the new plug-in requires conversion by the entire team which can't happen at this time). Once I understood the idiosyncracies, I've had only one problem working with the plug-in.
Our solutions contains many projects that are built into a single deployment package. As such, each assembly is versioned the same. To accomodate this, and other common aspects, we have defined a common "SharedVersionInfo.cs" file which contains the AssemblyVersion and AssemblyFileVersion attributes typically found in the AssemblyInfo.cs file. This file is stored in an Assets folder beneath the solution folder and added to each project's Properties folder as a linked file. This works great from a version management perspective as we only have to change the version in one place and all assemblies are updated. However, Perforce has a problem with this when a new developer first opens the solution or when a new project is added. The only remedy we have currently is to remove all of the linked files (there are 3 per project in this solution), bind the project to source control, then re-add the linked files.
This isn't such a big deal when we add a new project but the solution contains 80 projects (and counting), so this isn't a viable remedy for a new developer!
My understanding is that the problem has to do with where VS thinks the binding root for each project is. After some research, I was led to find where the MSSCCPRJ.SCC files are for the projects. I found there are numerous SCC files scattered throughout the solution structure. So...
First question: Why are there multiple MSSCCPRJ.SCC files in my solution structure?
We also have several shared/common projects that we use in our solutions. This leads to the following folder structure:
/Source
/CommonTools
/ProjectA
ProjectA.csproj
/ProjectB
ProjectB.csproj
/MySolution
/Assets
SharedVersionInfo.cs
/Project1
Project1.csproj
/Project2
Project2.csproj
:
/ProjectZ
ProjectZ.csproj
MySolution.sln
Where both ProjectA and ProjectB are part of MySolution.sln
Second Question: How can I setup the bindings so the /Source folder is considered the root? This would ensure that all projects included in the solution are under the same binding root. Perforce considers this folder to be the root, how do I get VS and the plug-in to do the same?
Since no one else has offered up a solution, I thought I'd follow-up with my own findings for anyone else that comes across the thread.
First, I still have no idea why Visual Studio creates multiple MSSCCPRJ.SCC files but these are the key to establishing the "binding root" for a solution. It is critical that this file exist at the highest level necessary so that ALL of the projects in the solution are in sub-folders relative to the location of this file. In my example above, the MSSCCPRJ.SCC needed to be located in the /Source folder. Having it in the /MySolution folder caused the original problem when adding projects from /CommonTools into the solution.
That said, resolving the issue was no easy task. I had to manually edit the .sln and all of the .csproj files in Notepad. What I found was that some of the .csproj files had the following elements identifying the source control settings:
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
I don't know what SAK stands for, but my understanding is this tells Visual Studio to use the binding information contained in the .sln file.
I had to change these to:
<SccProjectName>Perforce Project</SccProjectName>
<SccLocalPath>..\..</SccLocalPath>
<SccAuxPath />
<SccProvider>MSSCCI:Perforce SCM</SccProvider>
where the SccLocalPath value is the relative path from the .csproj file to the MSSCCPRJ.SCC file.
I also had to change the SccLocalPathX and SccProjectFilePathRelativizedFromConnectionX statements for each project in the .sln file. The SccLocalPathX value should be the relative path from the .sln file to the MSSCCPRJ.SCC file - a dot (.) if in the same folder. SccProjectFilePathRelativizedFromConnectionX should be the relative path from the binding root to the .csproj file.
I wish I could say that having that in place, I never had to repeat these steps. Unfortunately, I still have to go in and make corrections every time I added a new project to the solution. Visual Studio still wants to use SAK for the elements in the .csproj file and sometimes the values in the .sln file aren't quite right.
But, at least I know what to look for and what needs to be done to achieve my goals. If anyone else has a better solution or a way to configure VS and/or Perforce so these settings are created correctly up-front, I'll gladly give credit.
Hope that helps...
In the main project of my VS Solution I have a Resources folder with some required external tools. When building and publishing the solution, I get a .\Resources* with all required files there.
So far so good.
However I have to move some files to the parent directory.
My first attempt was do so with the Post Build Events. It works and does move them the correct folder.
Nevertheless in the publish output they still appear in the Resources folder and I need them in the parent one :/
Is there any way to setup the target output path for resources in Visual Studio?
After some research and experimental, I solved my problem.
Still, here's what I learned in the process.
The first attempt was adding the file to the project root and mark it as a resource. After publishing it worked. But having those files in the project root its lame.
Since I needed some *.exe files compiled in another VS solution, added them as a project reference. Gave it a try and it passed the "Publish" test. But still.. not the best way to do it.
After that, with some scripting and a post-build event, I copied the required files to the correct folder. Works.. but after publishing, they don't appear in the package.
However, there is still a possibility with the Mage tool:
http://msdn.microsoft.com/en-us/library/acz3y3te.aspx
This lead to some promissing experiments, however they ended up helping me realize how limited the MS ClickOnce is, so I decided to try other tools.
Here's a good start to follow:
What alternatives are there to ClickOnce?
I had a similar situation once. I found it became more trouble than it was worth to customize output paths and such in Visual Studio, to the extent that I wanted.
I ended up letting Visual Studio do its own thing with regards to file/project structure, and wrote a post-build script to copy everything that was needed into a final, 'publish-ready' directory.
I then set the execution target in Visual Studio to the new location, so I could run/debug as normal, but with the new folder that was organized how I needed it. Careful, I think this is a user project setting; so other developers will need to do this on their machines too, if they so desire.
I do recall changing some output paths and such to make the post-build script more simple. But changing things like that can lead to annoyances when you add new projects to the solution; you might need to configure them to match. It's all a trade-off :)
Two ideas:
Maybe you could move your resources into another project - a project just for resources - and then set their Build Action to Content and Copy To Output to true. Then reference this new project and build the solution. (This may not work as you want, just an idea).
Why not make your resources embedded resources instead. Keep them all within the Resources\ directory and access them programatically?