Building Visual Studio projects to a common directory rather than bin? - visual-studio

Is it possible to build projects to a common directory, instead of the per project bin folder?
The purpose would be to make it easier to source control all my binaries. How can I do it and, what are the pitfalls of this approach?
You have the option to build projects to another directory (a common directory?) rather than the bin/debug and bin/release.

If you mean building your projects and putting the DLL files in a shared folder, yes, we currently do this, but we use this using continuous integration (CI), so we can know when a change in a project caused another project to break.
You may also experience problems when you use a version-specific DLL file as referenced in your other projects.
You can also, rather than having a bat file copy over the DLL files, use Visual-Studio's built in post-build command. It's the same as a batch file, with the exception that no special setup is required in CruiseControl to copy over the files. If a developer makes a change to the post build command it and check it in it will automatically be executed by CruiseControl.
Also, if you'd like your developers to shared the binaries I'd put them in source control to make sure everyone share the same DLL files rather than their own local built copy of the DLL file (which might be different than the actual build server as some compile directives might/might not be defined).

If you mean DLL files/assemblies, then you build to bin/release as usual, then copy the DLL files you require to a common directory and then reference those, so when you rebuild the original solution, you don't have to worry about which version you are using or recompile other related projects as the version hasn't changed in the common dir.

It happens that people build to another folder than bin (e.g. the bin folder in the solution directory rather than the project directory). I doubt you would have any problems doing this. But since you're going to check it in, you must remember to not have it read-only (so you can build over them). Source control programs often lock the files.
You could also consider having a bat script that copies the files to another location after a successful build.

For C++ projects:
Right click on the project -> Properties -> Linker -> Output File
set your directory there.
For C# Projects:
Right click on the project -> Properties -> Builld -> Output Path

I would not put your binary output into source control. Only put the source files, project files and solution files.

We use post-build scripts to copy to the intended location. This works, but is very fiddly (as the scripts are awkward to write & awkward to debug).

Related

Create Visual Studio Project for building using command

I have a solution where there is a dependency on 7zip's sfx. Out of desire to keep the entire solution (plus the sfx) managed and coordinated, I want to create a new project to house all the source files that is used by sfx, and when building, execute a command line that tells 7zip to build a sfx from the source files, and place into the output so that it can be then referenced by actual Visual Studio projects within the same solution.
I think I can figure the command line by using Build events and providing the appropriate macros to ensure that the 7zip's output is placed into the target folder with appropriate name so that it can be then correctly referenced by other VS projects. But what I am not sure about is what Visual Studio project I need to use or steps to take to tell Visual Studio that there isn't going to be any code to be compiled in this project and it just has to execute this script I give it.
The closest thing I can come up with is VS's Make project but I don't know if that is the right thing since this has nothing to do with Make at all.
So, what is the Visual Studio project template I need to use? If empty, then what configuration do I need to perform so that it won't try and look for some code files to compile but instead just execute scripts as part of the solution's build?
For now, it seems that using C++ Makefile Project works. I had to make few configurations:
1) I had to specify the project's "Configuration Type" as "Utility"
2) I used Pre-Build event and provided a command to invoke a batch file included in the project. The batch file then takes care of everything.
3) Normally, non C++ files are not considered for determining whether build is needed or if it's already up to date. To ensure that a new build is perform if the batch file or other key files are edited, I set the file's "File Type" to "MakeFile". Even though it isn't actually a Make file, it ensures that any edits made to the file will cause a new build.
The downsides I've found so far are:
1) C++ uses "Filters", not folders. Therefore, keeping the files in same directory structure is a big PITA. One can "include" files and get a one-to-one mapping between "Filters" and the actual directory structure on disk but it's annoying and tedious. Wish it was a C# project
2) I'm a bit wary about how it will detect new files or other changes for files that I didn't explicitly set to "MakeFile". I expect the source to be stable but I worry that when I realize I need a new file and add it, I might forget and not notice that the build is not correctly including the new file.
I'm not sure if this is the best method but this works for my purpose - having a project to manage external tools as part of bigger build process.

Linked project references aren't being copied to target folder

I have 2 c++ projects in a solution.
ExecB (an executable) depends on ProjA (a dll).
So in ExecB's properties I add ProjA as a reference, and select Copy Local = true.
The problem is, ProjA's dll isn't being copied to ExecB's output folder folder. So the executable obviously doesn't run.
Any suggestions ?
For C++ projects, the Visual Studio template/wizard sets the Output Directory to a subfolder of the solution: $(SolutionDir)$(Configuration)\. This is so the DLL Search Path works well for the developer. It even works if you have added projects to the solution from outside the solution folder hierarchy; The build will put all binaries into the output folder for that solution.
If this isn't working, check the Output Directory property on all platform/configuration combinations of all your projects. Also make sure that the Build Configuration Manager shows that your selected solution build is building all the projects appropriate for the solution platform/configuration.
The Copy Local in Project References that you are trying applies only to referenced .NET assemblies. The docs are ambiguous and too terse on that. (Most often undistinguished use of "assembly" means .NET assembly rather than WinSxS assembly.)

Utility that extracts necessary files from a VS2010 solution folder?

I'm looking for a utility that copies all files from a VS2010 solution folder, which are necessary to build the solution, but ignores all other files (.obj files etc). My intended use is for emailing solutions or making them available on a blog etc.
I'd prefer a utility that's portable (runs without having to be installed), but if there is none, I'll settle for whatever's available.
You may want to consider something as simple as a script (via .bat or powershell) that simply runs the solution's build with a /clean and then zips up the entire folder structure into an archive.
No need to be fancy, especially when project can need any number of impossible-to-know files to build. (What happens when a new language is released like F#? If you'd written your tool 3 years ago, you'd have to modify it for that. What happens if someone needs a .txt file or a .mak file to build?)
In the past I've created a new configuration within VS.NET (e.g. Deploy) which builds the code in release mode. I also set the output path for the main application project to build into a separate folder in the root of the project.
If it's a web application, this is a little more problematic as it won't copy the support files. To get over this I use a nant script to copy all of the appropriate files, that are needed but aren't included in the build, into the aforementioned build folder.

Place all output dlls in common directory from Visual Studio

I have a couple of different solutions, in which some projects may depend on output from projects in other solutions. To manage this, I've been copying dll files from the /bin/ folder in each project to a shared library location after build, and then copy/reference them from there to the dependent project.
However, as the library solution gets larger, this tends to become unmaintainable. Too much of my time is being spent traversing solution directories in Windows Explorer looking for /bin/ folders, and trying to figure out which one, or which ones, of the dll files from each one I need.
Is there any way to give Visual Studio a hint that I want all projects in a solution to have the same output directory? For example, a /bin/ folder directly under the solution folder, where all projects put their output.
If possible, I'd like to achieve this without hard-coded post-build events that copy the files, since that will fail if a project output changes file name, or adds another file. I'd rather like to change the location of the actual output directory - the location of $(OutDir), if you will.
I know you said you don't want to use post build events, but your reason as to why not intrigued me. It sounds like you might be hard coding the name of the .dll in your post build event. That can easily be avoided.
xcopy "$(TargetDir)*" "c:\common\" /Y
The * would just cause everything in your bin/Debug/ folder to get copied to your common folder. You could also just copy dlls if you want. Or, if you use $(TargetPath), you'll copy just the 1 dll that is the result of the project, and not any other related dependencies.
UPDATE
The way we do it is each projects entire bin folder is copied to a subfolder. Suppose you have 2 projects, WebUtil and HtmlParser, where WebUtil depends on HtmlParser. For both projects, use xcopy "$(TargetDir)*" "c:\common\$(ProjectName)" /Y. This will create c:\common\WebUtil\ and c:\common\HtmlParser. In WebUtil, add a reference to c:\common\HtmlParser\HtmlParser.dll. There will now be 2 copies of HtmlParser.dll in c:\common.
c:\common\HtmlParser\HtmlParser.dll // the most recent build.
c:\common\WebUtil\HtmlParser // what was the most recent build when WebUtil was built
This has all kinds of advantages. If you change the API of HtmlParser, WebUtil will continue to work, since it will have the older HtmlParser.dll until you try to rebuild WebUtil (at which point you'll get build errors because of the changed API).
Now, if a 3rd project got in the mix that depended on WebUtil, and you're using some part of WebUtil that exposes classes in HtmlParser, then you'll need to add a reference to both projects from your new project. When you add a reference to HtmlParser.dll, use the one in c:\common\WebUtil. You do this because you're only including it as a necessary requirement of WebUtil. Now you'll always have the version of HtmlParser.dll that matches your current version of WebUtil.dll.
I hope that makes sense. It can definitely be a tricky thing to manage. Just wait till you have to start pulling down all your dependencies using svn:externals =P
You can set the output directory in each project properties.
Right click on the project, select Properties
For C#, it is one of the Build property page, under Output, Output directory.
In VB.Net projects, it is on the Compile tab, in the textbox at the top.

How to associate external files with an assembly

Let's say you have a class library project that has any number of supplemental files that also need to be included with the compiled assembly (e.g. simple text files or even a legacy unmanaged DLL that's wrapped by the assembly as an interop layer). While embedding the supplemental files into the assembly itself is relatively straightforward, we have situations where this is not possible or just undesirable. We need to have them as "sidecar" files (i.e. files alongside the assembly, potentially in subdirectories relative to the assembly)
Adding those files to the project with an appropriate value for "Copy to Output Directory" specified appears to be sufficient for projects that are completely self-contained within a solution. But if a separate project in another solution adds a reference to the assembly, it does not automatically pickup its sidecar files. Is there a way in the project to somehow mark the resulting assembly such that anything referencing the assembly will also know it needs to include the associated sidecar files? How do you do this?
You can use al.exe, but there also appears to be a C# compiler option. You want to create a multifile assembly using the /linkresource C# compiler option. Instructions are here, but the command is similar to this:
csc /linkresource:N.dll /t:library A.cs
Where N.dll is a native DLL that will go wherever the managed assembly goes (including into the GAC.) There's a very clear description at the link I provided.
Have you tried creating a setup for your solution ? There's an option of including sidecar files targeting to application installation directory.
Another option would be to include the sidecar files in the Assembly resources and un-wrap them to disk when run for the first time.
What if you create a merge module containing the library plus its dependencies? Your installer will then need to reference this module, but you will ensure all of the necessary files will be present.
Unfortunately there doesn't appear to be a lot of built-in support in Visual Studio for this, although I can definitely see the use case.
If you use Subversion for your source control, then you could link in an external reference as an externals definition. This would bring in the source code, and you'd be making a reference to the necessary assembly as a project reference instead of a DLL reference, and then the copy to output directory rules would come into play.
If that's not possible, another solution would be to include commands in the pre/post-build events of your in-solution project to copy the most up-to-date sidecar files from the remote assembly on a build. Of course this comes with the caveat that it doesn't set itself up automatically when you include the DLL in your project; you have to take manual steps to set it up.
I deal with this some time ago. Its a common problem.
You can create some postbuild actions:
http://www.codingday.com/execute-batch-commands-before-or-after-compilation-using-pre-build-or-post-build-events/
Hope this helps... :)
It appears to me that you're using the wrong type of reference. There are two types of references- Reference and ProjectReference. Reference is an explicit reference to a specific assembly. ProjectReference is a reference to another project (say .csproj).
What you're looking for is ProjectReference. VS and the default MSBuild targets are setup to do CopyLocal. If you set CopyToOutputPath true for your "sidecar" files, any ProjectReferences to this project now will also pull in the same files.
I'm not sure if you can to ProjectReferences across solutions in the IDE. I deal a lot with MSBuild where sln files are not relevant and this is how I deal with it.
What we did in our project is that we created as separate build file to do all those stuffs.
In your build file you can have tags to build your main solution, then add tags to copy files you need after build.
NAnt is also your option, but right now I'm happy using Rake as my build/debug automation.
Since this cannot be integrated within Visual Studio, what I'm doing is I create a task (either in MSBuild, NAnt or Rake), that executes vsjitdebugger.exe in the end to attach it to my Visual Studio when debugging.
These are just my styles for now, you can maybe create your own style.

Resources