How does Visual Studio determine the order to compile IDL files? - visual-studio

I have a COM project that contains a number of IDL files, some of which are imported into other ones. How does Visual Studio decide which ones to compile (using MIDL) first?
I want to control the order. I have a master IDL file which contains my library declaration with several imports, and I get a build error if it is not the first one compiled.
(If any of this sounds really weird... I'm new to COM/ATL, and it's really, really confusing).

You can't ask Visual Studio to build .ild files in a specific order. Instead you can #include some of .idl files into other .idl files and set the files you imported to "excluded from build". This way MIDL will not compile the imported files separately, instead it will include their contents into specific place of another file and compile as the part of that file (same effect as with C preprocesor #include).

You can make Visual Studio build things in any order you want, there are 2 ways to do this:
Put in a pre-build step in which you can get it to build the ones you wish to build first.
Put the ones you want to build first in a separate project and get it to build that project first by making your other one dependent on it.
This is what you should do if you cannot modify the idl files. If however one idl file really does depend on another and you can modify them, then do what was suggested above and get one to include the other.

Related

Can I delete every other file than the compiled program?

When I build solution in Visual Studio (2022), it generates an EXE (or DLL if I chose a class library) just as expected, except it also generates some files, like PDB, and some CS files. I know what most of them do, but if I am making a software, which consists of multiple of these files, I wouldn't want or like some people looking at the application directory and find source files and/or source code and solutions. This makes me come up with a question: Would deleting every single file except the compiled EXE or DLL impact their usability, or is there any other circumstance(s) to avoid creating these files, like SLN or PDB?
Thanks in advance :)
I have not tried anything, because, I simply don't know how to prevent VS from creating these files, except compiled files.
The .pdb files are outputs of your compilation. You can suppress them with:
<DebugSymbols>false</DebugSymbols>
The other files, like .cs and .sln are inputs to your project. Deleting them will mean you cannot build your program any more. I don't understand why you would want them to be deleted. If they're appearing in your output directory, check that you don't have "Copy local" (CopyToOutputDirectory) set on those items in your project.

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.

How to pull output (.dll) from one project to another?

As the part of a bigger solution, I have two projects.
One is c++ library packed as a DLL, and other is .NET wrapper for it.
What would be the best way to indicate to Visual Studio that output DLL from first project is to be pulled into the destination folder of second project, and more: for projects that use wrapper, will they pick up also the DLL from the first one.
I could do it with post-build steps, but I'm after something more sophisticated. Is that possible?
EDIT: we could also ask: "How to add unmanaged reference?"
I guess I found a solution, that might be satisfying...
Steps:
in wrapper project, I'll add a DLL that is now present in the output directory of the LIBRARY. Any configuration will do.
Pre-build step for the wrapper project should COPY output of the library that is currently configured to be built into the source directory directly
option for the file will be 'do not build' and 'copy to output directory if newer'
in version control, that file will be IGNORED by version control (I use svn, hope it's possible in others as well).

Custom Build Rules in Visual Studio, with multiple outputs

We have a C++ project that uses a custom object-relational-mapping system, in which tables are defined by .tbl files. These are then run through a code-generator that creates, for each, a .h and a .cpp file.
I'm trying to get a custom build rule working for this, in Visual Studio 2008 and 2010.
This is what I have, so far:
<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile
Name="z_dbbld"
Version="8.00"
>
<Rules>
<CustomBuildRule
Name="z_dbbld"
DisplayName="z_dbbld"
CommandLine="$(SolutionDir)\tools\z_dbbld $(InputName)"
Outputs="$(InputName).cpp"
FileExtensions="*.tbl"
ExecutionDescription="z_dbbld $(InputName)"
>
<Properties>
</Properties>
</CustomBuildRule>
</Rules>
</VisualStudioToolFile>
The problem is the dependencies. When I run a build on a clean checkout, where none of the files exist, I get "Cannot open include file" errors, for .h files that are generated by this rule.
I've tried changing Outputs to "$(InputName).h", and I still get the errors.
Now the thing is that these files are created, when the code generator runs. If I compile again, I don't have the errors, because all of the files were created in the first pass. But it makes doing a clean, automated, build from fresh checkout not work.
Any ideas?
I think you need to specify the Output files in the main part of the build (looking at the very last sentence of http://msdn.microsoft.com/en-us/library/hefydhhy.aspx). Probably the easiest way to do that is to add a reference to the files when they exist and then delete them and see if the codegen step runs like it should.
The answer given by sblom is correct, but it does not explain the reason.
For each build rule (custom or native) the VS build system needs to know the complete list of inputs and outputs so that it can decide what part of the project needs to be built.
Your build rule declares the generated .cpp file as an output, so VS knows about it and will automatically build this file for you. Since you omitted the header file, VS does not know about it, so any source files that include this header will not know where to get it from and fail to build. A work around to get the build to work in this situation is to add the directory where this .h file is located to your include path, and then #includes of this file will work. You are basically enabling VS to know about this file in a different way.
Conversely, if you change your build rule to declare the header file as output, then source files that include it will know where to get this file from, but now VS does not know about your .cpp file so it won't build it. A work around for this case is to explicitly add the generated .cpp file to your project as a source file. Like in the above case, you are using a trick to get the build system to recognize the generated file.
But while the workarounds above will get you going they are not the best solution, since they just compensate for VS not knowing about a file. The best way to address this problem is to declare both the .cpp and the .h files as outputs in your rule, separating them with a semi-colon. This will enable VS to apply the correct behavior to both files.

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