A third party software that we build but typically do not modify in any way has some odd behaviour: Since it is build as a static lib, the PDB file it creates is called vc.pdb and is located in the softwares' intermediate folder. Now it creates about 12 of those pdb files, all in different folders, all with the same name for different libraries and different configurations.
When we integrate this third party software in our code we get the LNK4099 warning because the baked in path for the pdb is obviously not there on all machines. Due to the fact that the third party software generates multiple .lib files in one output directory we cannot place the vc<...>.pdb file along with them.
So I am looking for a way to patch the lib files baked in pdb name to something I have under my control. Does Visual Studio build tools provide a way to do that?
Edit: Let me explain in greater detail what we are doing:
We decided to integrate some third party static lib in our projects. The project itself comes as a source package. One developer or the build server or whoever builds this source package which produces statically linked libs called a.lib and b.lib in various build configurations. With them the default visual studio configuration produces vc110.pdb files, because they are called all the same VS automatically put them into $(IntDir). So the pdb files are all over the place.
Now we commit these third party binaries to our VCS for the given project X.
Whoever now uses the static libs in project X has to link them into the final binary. This is the time where the LNK4099 is generated because the pdb files are not in the VCS and not available on this machine.
But we actually cannot commit all the vc110.pdb files, because this is useless. Since the full qualified path is build into the static libs, no other user will be able to replicate that. During linking the full path to the PDBs cannot be found so it looks for vc110.pdb in the location of the lib file.
Since the third party package decided to put a.lib and b.lib in the same directory we can never properly place the pdb files along with them unless we modify the build of the third party package and either rename the pdb files in the vcxproj or split the generation of libs to be in different directories (also in the vcxproj).
That's the point: I would like to not modify the build files of the third party at any time, I would like to be able to use a plain fresh download of this third party package and build it with some "simple" batch script.
The default results of this package are:
/Bin
/Debug
a.lib
b.lib
/Release
a.lib
b.lib
/Temp
/A
/Debug
vc110.pdb
/Release
vc110.pdb
/B
/Debug
vc110.pdb
/Release
vc110.pdb
What I really want is to patch the generated files after the build.
My "simple" batch (or whatever) script could for instance rename the pdb files to a.pdb and b.pdb, which of course would not be enough because the linker would still look for vc110.pdb as it is the compiled-in name. That is why I am looking for a way (via tools like lib or dumpbin, etc.) where I can patch my generated libs to the new pdb name.
Like that:
$ magic /showPDB a.lib
> D:\some_users_machine\unique_path\package\Temp\A\Debug.vc110.pdb
$ magic /newPDB a.lib d:\path\a.pdb
> New PDB name is d:\path\a.pdb
When the consumer then links my patched a.lib it would not try to look for a.pdb at the path above. It would of course also not be found on most machines but then linker would also look for a a.pdb in the location where a.lib is located and that's were I could place it now for all.
Edit 2: For the close due to opinion base: I am looking for a technical way to modify a static lib's baked in pdb location
Take a look at the linker option /PDBALTPATH. This allows you to specify a different PDB path that will be embedded into your binary.
/PDBALTPATH:pdb_file_name
MSDN Article: /PDBALTPATH (Use Alternate PDB Path)
Related
I have a nuget package which has .dlls files that it automatically copies to a directory when the program is compiled. Is there a way to specify where the dlls files will be copied to?
I know it's possible to modify the .targets file of the package but assume I don't have access to the package. The project is managed through git so I'd rather not have to distribute binaries along with the licenses included in the package. Currently when someone downloads/compiles the source, the nuget package is automatically downloaded through nuget restore. Is there a way to override the .targets file of the package?
I'd prefer not to use scripts to manage the dll files if possible. Also this is for a C++ project and I know nuget has restrictions based on the languages used.
If your question is asking if there's a simple configuration file or something similar where you can write "copy contents of package X to location Y", then no.
To most people, the difference between the various components in the build system are not important, so it doesn't matter to them if NuGet copies something or their project's SDK copies something, or MSBuild copies something. However, since you're now trying to do something more advanced, these differences may be important. NuGet only writes/copies files at restore (and therefore only to the packages folder, not the project output folder), but after restore, NuGet doesn't run at all. NuGet just makes the files known to the rest of the build system, and those components are responsible for deciding what to do. For example, where to copy files.
Since both C++ and .NET projects use MSBuild, the same debugging techniques can be used. From a "developer command prompt", build your project using the -bl switch to generate a "msbuild.binlog" file. You can open this file with the MSBuild structured log viewer. You can then use the search to find where in the build each dll is copied, and what the copy arguments (including destination) is. You can also look to find where the item that defined the file to be copied was created. Then, you can write an MSBuild target in your project file (or another file that gets imported by your project file) that runs at an appropriate time and updates the item to set the destination you want the file to be copied to. But, MSBuild is a scripting language, and you said you didn't want to write a script, so you might not like this approach. And if you're not already knowledgeable about MSBuild scripting, it's probably more effort than writing a powershell script. But at least it would happen automatically as part of the build (and therefore happen when you build and debug in Visual Studio), and not be some other process that needs to be manually run.
I am using cmake to generate my solution files and I'm doing that out-of-source. So I have a myproject folder and a myproject_build folder. When I save my ReSharper settings in team solution, it creates a dotsettings file in the myproject_build folder.
C:\
myproject
.hg
CMakeLists.txt
myproject_build
myproject.sln
myproject.DotSettings
How can I make sure that saving these settings goes into the source folder and be sure that all team members have the same settings?
I guess I would place a common dotsettings file into myproject, the file that you and your team will modify in the future. During generation of the solution into myproject_build you should generate a myproject.sln.dotsettings file as well, that need to hold a reference onto the file from myproject. You can include any other dotsettings file by going to ReSharper | Manage Settings and then right-click any layer (team-shared in your case) and add the particular file.
How does Visual Studio process the App_Code folder when a change is made or detected in it? Not IIS or ASP.NET.
I want to gain a better understanding of why Visual Studio freezes for long periods of time whenever I save a code file inside a large App_Code folder of a website project. Alternatively, I could ask: why does Visual Studio not exhibit these same freezes when processing a file inside a class library that is equally large?
Ideally I would like to see official documentation cited from Microsoft of the issue at hand of processing the App_Code folder in Visual Studio and what happens that differs from processing a class library for example.
The App_Code folder is not explicitly marked as containing files
written in any one programming language. Instead, the ASP.NET infers
which compiler to invoke for the App_Code folder based on the files it
contains. If the App_Code folder contains .vb files, ASP.NET uses the
Visual Basic compiler; if it contains .cs files, ASP.NET uses the C#
compiler, and so on.
If the App_Code folder contains only files where the programming
language is ambiguous, such as a .wsdl file, ASP.NET uses the default
compiler for Web applications, as established in the compilation
element of the application Web.config file or the machine-level
Web.config file. Compilers are named build providers and a build
provider is specified for each file extension in an extension
element.
See the documentation here.
It recompiles all code in this folder in a separate assembly, then reference this assembly in your project.
You should be aware that a double reference could occur if you include these files as compilable in your project. In this latter case, the files are at the same time compiles in a separate assembly (with a temp name) which is referenced, and also compiled in the bin folder. This is the start of the horror show ...
These performance notes about the App_Code folder are slightly dated but likely still apply to the project type:
2) Keep the number of files in your /app_code directory small. If you
end up having a lot of class files within this directory, I'd
recommend you instead add a separate class library project to your VS
solution and move these classes within that instead since class
library projects compile faster than compiling classes in the
/app_code directory. This isn't usually an issue if you just have a
small number of files in /app_code, but if you have lots of
directories or dozens of files you will be able to get speed
improvements by moving these files into a separate class library
project and then reference that project from your web-site instead.
One other thing to be aware of is that whenever you switch from source
to design-view within the VS HTML designer, the designer causes the
/app_code directory to be compiled before the designer surface loads.
The reason for this is so that you can host controls defined within
/app_code in the designer. If you don't have an /app_code directory,
or only have a few files defined within it, the page designer will be
able to load much quicker (since it doesn't need to perform a big
compilation first).
-- http://weblogs.asp.net/scottgu/archive/2006/09/22/Tip_2F00_Trick_3A00_-Optimizing-ASP.NET-2.0-Web-Project-Build-Performance-with-VS-2005.aspx
I need in Chrome extension these actions:
Download binary file to temp
Unzip it (it's clear .zip package)
Move files from unpacked directory, to directory of my extension
Delete temp files
I've been looking for similar what Firefox Scriptable XPCOM interfaces offer, https://developer.mozilla.org/en/XPCOM_Interface_Reference
Is there any simple way to do this, or I need to create the components myself in C/C++ and one of NPAPI, PPAPI, NSPR ?
Our product includes several DLLs built from open source into files with default names as delivered by the open source developers. We're careful to install the files in our own directories and we carefully manage the search path (only for our processes) to keep the loader happy.
Another developer -- a towering intellect -- decided it would be easier to install their own build of some of the same open source into C:\WINDOWS under the same default DLL filenames. Consequently, when we launch a process which depends on these open source DLLs, the system searches C:\WINDOWS before our directories and finds the DLLs installed by the other developer. And they are, of course, incompatible.
Ideas which have occurred to me so far:
rename all our DLLs to avoid the default names, which would only make
it less likely we would encounter collisions
load all our DLLs by full path so the loader captures their names into
RAM and doesn't search anywhere else the next time they are requested
For various reasons, neither of these options is palatable at the moment.
What else can we do to defend ourselves against the towering intellects of the world?
You've got only two options: deploy the DLL in the same directory as the EXE (that's where Windows looks first) or using manifests and deploy the DLL to the Windows side-by-side cache. I don't think the latter option is common in the Open Source world but it is the only real fix if you want to share DLLs between different apps.
To add to the already excellent answers, you have a couple more choices:
The preferred solution(s) to this problem, supported since Windows XP, is to turn your dll's into a win32 assembly (They don't have to be .NET but the documentation on creating win32 assemblies with strong names is appallingly light so its easy to get confused and think this is a .NET only technology).
An assembly is noting more complicated than a folder (With the name of the assembly) containing the dlls and a .manifest (With the name of the assembly) that contains an assemblyIdentiy element, and a number of file nodes for each dll in the assembly.
Assembly based searching works even when dlls are statically linked!
The easiest option is to create unversioned assemblies and store them in the same folder as your .exe files (Assuming all your exe's are in a single folder).
If the exe's are in different folders, then there are two ways to access shared assemblies:
You can store your assemblies in a private alternate location if you expect your application to be used on Windows 7 and higher. Create a app.exe.config file for each of your exe's, and point a probing privatePath element to a common folder where you are storing the assemblies.
If you are ok with requiring administrative access to perform installs, (via MSI's) then you can deal with the appallingly bad documentation (well, absent documentation) that deals with giving your assemblies a strong name, and then store the assembly in WinSxS.
If you can't, or do not want to bundle your dlls as assemblies then this page covers dll search order
Using functions like SetDllDirectory are only going to help for dlls loaded dynamically at runtime (via LoadLibrary).
Dll search order used to be:
Directory containing the process exe
Current directory
various windows folders
PATH
Which you could have used to your advantage - launch each exe, setting the "current" directory to the folder containing the OSS dlls.
With the advent of SafeDllSearchMode the search order now is:
Directory containing the process exe
various windows folders
Current directory
PATH
Meaning theres now less control than ever :( - It goes even faster to the "untrusted" c:\windows & System32 folders.
Again, if the initial dll is being loaded via LoadLibrary, and its the dependent dll's that are the problem, LoadLibraryEx with the LOAD_WITH_ALTERED_SEARCH_PATH flag will cause the following search order (Assuming you pass a full path to LoadLibraryEx) :-
Directory part of the Dll path passed to LoadLibraryEx
various windows folders
Current directory
PATH
The directory from which the application loaded is normally the first directory searched when you load a DLL. You can, however, use SetDllDirectory to get the "alternate search order". In this case, the directory you specify to SetDllDirectory gets searched first.
There is also a SafeDllSearchMode that affects this to a degree. Turning it on excludes the current directory from the search.
Maybe just compile them to a static library?
Why not?
Also, the current directory, where the exe is activated from is searched before c:\windows.