Visual Studio graying wrong #ifdef'd passages in C/C++ code - visual-studio

I'm working on a large, inherited C++ (really, mostly C) project developed and maintained under Visual Studio 2008. Technically, in Visual Studio terms, it is a "solution" consisting of eight "projects", and therein appears to be the rub.
As I'm sure most of you know, Visual Studio grays out the code that it believes to be #ifdef'd out. What I'm finding, though, is that it doesn't seem to do this correctly for the different projects. To keep matters simple, let's just call them Proj1, Proj2, ... Proj8. When I'm working on the Win32 Debug configuration of Proj5, I'd expect that the macros defined in the C/C++ Preprocessor properties configuration of Proj5 would determine what is grayed (or at least that there would be some straightforward way to make it so). Instead, I seem to be seeing views based on properties of Proj1. That is, if Proj1 defines some preprocessor macros that eliminate part of the code, I'm seeing that part grayed even when I'm working on Proj5. And the macros for Proj5 have no effect at all on what I see.
Yes, I did a complete clean and build (several, actually, and even saved everything off to SVN and started in a new top-level folder), and so I'm pretty sure this is not because of some vestigial files produced by an old build. And I'm pretty sure that in other respects Visual Sourcesafe "understands" the context correctly, because (1) the Build menu contains options related to Proj5, not Proj1; (b) at the bottom of the Project menu is "Proj5 properties..." not "Proj1 properties..."; and (c) there is no question that the #ifdef's are working in the program that is built: there are major feature differences, and they are as I'd expect them to be.
ADDED 27 Sept 2010 I still don't have an answer, so let me try this a different way: Assuming I've already run successful builds (which I have) is there anything other than the preprocessor properties and configuration of the currently selected project (and, as noted below, those of individual files, but that is moot in this case) that should influence what code is grayed?

Please see if these preprocessor directives might be set for the individual files. You can do this by right-clicking on a source file and selecting "Properties" from the context menu. It's somewhat counterintuitive to think that the directives can be set for individual files, not just for projects.
If that doesn't help, your best bet might be to use a text editor to look for the problem preprocessor definitions in each of the project files to try to get a better idea of what might be happening.

VS2010 is supposed to help with this. In VS2008, the no-compile browse cache is done after preprocessing, so it can accommodate only one set of macro definitions.
I don't believe that "Build Clean" or "Rebuild" will delete the .ncb files, since they are not part of the build process at all. I do know that deleting these files by hand fixes all kinds of weird behavior, but I'm afraid that in your case it's not going to be a lasting solution (the .ncb files will still get filled in based on a single configuration.)

Make the project the Startup Project and Remove and Re-add the offending Preprocessor Definition
Details:
I found a process that that fixes my MFC projects when this happens (at least temporarily). First I set the project I am working on as the startup project. Do that by right-clicking the project in the solution explorer and selecting Set as Startup Project. Then I go into the preprocessor definitions for the project and deleting the one that is not triggering and clicking OK. You will see a little progress bar a few seconds later appear in the lower right. Once it finishes, go back into preprocessor definitions for the project and add it back in again and click OK. After the little progress bar finishes again, you should see the correct code active again.

Related

Visual Studio 2019: Strange behavior using property sheets

I wish I could provide a better description, but this is hard to describe succinctly.
Let me start with some background. This is a C++ solution using Visual Studio 2019 Community Edition. It has 12 projects of different types (DLLs, static libraries, and executable tests) and 4 build configurations ((Release, Debug)x(Win32, x64)). Keeping all the properties the same across projects and configurations has been a massive pain, so I decided to try using property sheets so that I could have the properties shared across projects. Given the structure of my solution, the property sheets are themselves somewhat complicated, but it's an improvement over what I had.
However about halfway through this migration I noticed some odd behavior. When I inspect the properties for one of my projects (a static library), the properties page is almost totally empty. Not only the properties I have changed with my sheets are missing, but even the default properties that you would expect.
However when I build this project, I can tell that most of the custom properties are in fact set correctly despite being missing, so it would seem like a UI bug, except some properties are not set correctly, for example the build log is not written to the correct location despite being set in the property sheet. This makes me worried that other more important properties may not be set correctly as well, but it's hard to know which properties are getting set and which are not.
I have another static library project that is set up in the same way with the same property sheets, and it behaves normally. It shows the expected properties in the project properties, and the build log is even in the correct location.
It gets even stranger. When I run the build from the command line using msbuild or devenv, the build log is written to the correct location. This suggests that building from the command line is working correctly, and that building from Visual Studio is not the same as building from the command line.
I ran msbuild -pp to see the expanded project file, and it looks correct. I diffed this project file with another static library from my solution that is working normally, and the diff is as expected, only the project names, paths, and source files are different. I did this diff on the expanded projects files too and they were the same except the expected differences.
I have closed and reopened Visual Studio countless times. I have also unloaded and reloaded the project. I have even tried deleting the .vs folder. None of these had any affect.
Here is a link to my code.
Screenshots demonstrating what I mean.
Is there any way to fix this? Have I done something wrong? I would like all of the properties from my property sheets to show up in the project properties, and I especially need all of them to apply when building the project.
Moving the <ItemGroup>s containing the source files below the <ImportGroup>s in my project file (.vcxproj) fixed the problem. I cannot explain why this works, or why this was ever a problem in the first place, but it fixed it.

Building related projects on Visual Studio

I am a Visual Studio noob. My background is more Unix-related and mostly used to building things via scons or make. I don't even have much Eclipse experience.
Anyway, I am frustrated how it seems very difficult to move files between projects in VS. (I am running Visual Studio 2013). For example, suppose I have a ProjectXRel (release) and I want a ProjectXDev (development). I want them both to be runnable, and the dev version might have just a few editing changes that differ it from the rel version.
The intuitive thought is to just copy the files from ProjectXRel to create ProjectXDev, but VS seems to fight me on that (it wants to rename all the namespaces to the title of the project).
Also, some of the files, like .cs files derived from .dbml via OR designer, seem uncopyable, and rely on one replicating the process of using the utility to having valid files. I'm used to a project being defined by its files, but that's not really the case in VS. Instead it seems defined by process steps used to create and organize the files.
Also, do serious developers just use command line calls and powershell? That's seems harder, but at least you know what the %#$$# is going on.....
So, the basic question is, how does one replicate an existing project to produce a similar one for development purposes? (I know source control such as git could help with that, but that's not an option for this situation.)
Thanks!
You should be using the same project for both Development and Release.
The things that are different between Development and Release should be stored in a config file (web.config or app.config, depending on what type of project).
You should then be using Configuration Transformations to transform that .config file into Development or Release.
In Visual Studio, right click on the project and click Add New Item, select "Application Configuration File".
In this file you can put connection strings or key/value pair settings in the AppSettings element (MSDN Link).
Once you have your basic settings defined, you can then right click on the config file and click Add Transformation. This will add transformations for each of the Project Configurations you have. (by default Debug and Release).
It will look like this:
Now you can build deployment packages.
Or install Slowchetah and then when you press F5 to debug it will run the selected project configuration with the configuration transformation applied.

Visual Studio 2008 Unnecessary Project Building

I have a C# project which includes one exe and 11 library files. The exe references all the libraries, and lib1 may reference lib2, lib3, lib4, etc.
If I make a change to a class in lib1 and built the solution, I assumed that only lib1 and the exe would need to be changed. However, all dll's and the exe are being built if I want to run the solution.
Is there a way that I can stop the dependencies from being built if they have not been changed?
Is the key this phrase? "However, all dll's and the exe are being built if I want to run the solution"
Visual Studio will always try to build everything when you run a single project, even if that project doesn't depend on everything. This choice can be changed, however. Go to Tools|Options|Projects and Solutions|Build and Run and check the box "Only build startup projects and dependencies on Run". Then when you hit F5, VS will only build your startup project and the DLLs it depends on.
I just "fixed" the same problem with my VS project. Visual Studio did always a rebuild, even if didn't change anything. My Solution: One cs-File had a future timestamp (Year 2015, this was my fault). I opened the file, saved it and my problem was solved!!!
I am not sure if there is a way to avoid dependencies from being built. You can find some info here like setting copylocal to false and putting the dlls in a common directory.
Optimizing Visual Studio solution build - where to put DLL files?
We had a similar problem at work. In post-build events we were manually embedding manifests into the outputs in the bin directory. Visual Studio was copying project references from the obj dir (which weren't modified). The timestamp difference triggered unnecessary rebuilds.
If your post-build events modify project outputs then either modify the outputs in the bin and obj dir OR copy the modified outputs in the bin dir on top of those in the obj dir.
You can uncheck the build option for specified projects in your Solution configuration:
(source: microsoft.com)
You can can create your own solution configurations to build specific project configurations...
(source: microsoft.com)
We actually had this problem on my current project, in our scenario even running unit tests (without any code changes) was causing a recompile. Check your build configuration's "Platform".
If you are using "Any CPU" then for some reason it rebuilds all projects regardless of changes. Try using processor specific builds, i.e. x86 or x64 (use the platform which is specific to the machine architecture of your machine). Worked for us for x86 builds.
(source: episerver.com)
Now, after I say this, some propeller-head is going to come along and contradict me, but there is no way to do what you want to do from Visual Studio. There is a way of doing it outside of VS, but first, I have a question:
Why on earth would you want to do this? Maybe you're trying to save CPU cycles, or save compile time, but if you do what you're suggesting you will suddenly find yourself in a marvelous position to shoot yourself in the foot. If you have a library 1 that depends upon library 2, and only library 2 changes, you may think you're OK to only build the changed library, but one of these days you are going to make a change to library 2 that will break library 1, and without a build of library 2 you will not catch it in the compilation. So in my humble opinion, DON'T DO IT.
The reason this won't work in VS2005 and 2008 is because VS uses MSBuild. MSBuild runs against project files, and it will examine the project's references and build all referenced projects first, if their source has changed, before building the target project. You can test this yourself by running MSBuild from the command line against one project that has not changed but with a referenced project that has changed. Example:
msbuild ClassLibrary4.csproj
where ClassLibrary4 has not changed, but it references ClassLibrary5, which has changed. MSBuild will build lib 5 first, before it builds 4, even though you didn't mention 5.
The only way to get around all these failsafes is to use the compiler directly instead of going through MSBuild. Ugly, ugly, but that's it. You will basically be reduced to re-implementing MSBuild in some form in order to do what you want to do.
It isn't worth it.
Check out the following site for more detailed information on when a project is built as well as the differences between build and rebuild.
I had this problem too, and noticed these warning messages when building on Windows 7 x64, VS2008 SP1:
cl : Command line warning D9038 : /ZI is not supported on this platform; enabling /Zi instead
cl : Command line warning D9007 : '/Gm' requires '/Zi'; option ignored
I changed my project properties to:
C/C++ -> General -> Debug Information Format = /Zi
C/C++ -> Code Generation -> Enable Minimal Build = No
After rebuilding I switched them both back and dependencies work fine again. But prior to that no amount of cleaning, rebuilding, or completely deleting the output directory would fix it.
I don't think there's away for you to do it out of the box in VS. You need this add-in
http://workspacewhiz.com/
It's not free but you can evaluate it before you buy.
Yes, exclude the non-changing bits from the solution. I say this with a caveat, as you can compile in a way where a change in build number for the changed lib can cause the non built pieces to break. This should not be the case, as long as you do not break interface, but it is quite common because most devs do not understand interface in the .NET world. It comes from not having to write IDL. :-)
As for X projcts in a solution, NO, you can't stop them from building, as the system sees a dependency has changed.
BTW, you should look at your project and figure out why your UI project (assume it is UI) references the same library as everything else. A good Dependency Model will show the class(es) that should be broken out as data objects or domain objects (I have made an assumption that the common dependency is some sort of data object or domain object, of course, but that is quite common). If the common dependency is not a domain/data object, then I would rethink my architecture in most cases. In general, you should be able to create a path from UI to data without common dependencies other than non-behavioral objects.
Not sure of an awesome way to handle this, but in the past if I had a project or two that kept getting rebuilt, and assuming I wouldn't be working in them, I would turn the build process off for them.
Right click on the sln, select configuration manager and uncheck the check boxes. Not perfect, but works when Visual Studio isn't behaving.
If you continue to experience this problem, it may be due to a missing or out of date calculated dependency (like a header) that is listed in your project, but does not exist.
This happens to me especially common after migrating to a new version (for example: from 2012 to 2013) because VS may have recalculated dependencies in the conversion, or you are migrating to a new location.
A quick check is to double-click every file in offending project from solution explorer. If you discover a file does not exist, that is your problem.
Failing a simple missing file: You may have a more complicated build date relationship between source and target. You can use a utility to find out what front-end test is triggering the build. To get that information you can enable verbose CPS logging. See: Andrew Arnott - Enable C++ and Javascript project system tracing (http://blogs.msdn.com/b/vsproject/archive/2009/07/21/enable-c-project-system-logging.aspx). I use the DebugView option. Invaluable tool when you need it.
(this is a C# specific question, but a different post was merged as identical)

Finding out-of-date or missing dependencies or output files in a Visual C++ solution (or: Why does VS insist on rebuilding projects without changes?)

I've got a solution containing multiple projects. I'm only changing the code in one of them, but every time I hit Ctrl+Shift+B, Visual Studio rebuilds all of the others.
I want it to build the other projects, so this is good. What's not good is that, normally, it would see that there was nothing to do. I have a wonky dependency somewhere, so this isn't working.
Is there a tool or macro (or switch) that'll explore the dependency tree and tell me which files are missing or out-of-date, so that I can get it to stop?
I know that I can solve this specific case, by (e.g.) touching all of the project files.
Unfortunately, I've often seen this situation when a file is configured to produce an output file (e.g. an IDL file is configured to output a typelibrary, but doesn't contain a 'library' block, so it'll never create a TLB).
This wouldn't be resolved by touching all of the project files, so I'm looking for something more general to add to my personal toolbox that'll easily tell me why a file is being rebuilt, whether it be because it's older than a dependency, or because the project is misconfigured to expect an output file that will never be produced.
In Options / Projects and Solutions / Build and Run turn up the MSBuild project build output verbosity to Detailed. It should give you an idea of why it is rebuilding all the projects.
If I understand you right, you might solve this by touching all your project's files. It may be caused by a source-file having a last-modified-time that's in the future.
Edit:
I know that I can solve this specific case, by (e.g.) touching all of the project files, but I'd like to add something to my personal box of tricks that I can use in the future, in the general case.
I'm confused - what's the 'general case' of this problem?
Not that I've found. If you know that a project is not going to change often, you can tell the Configuration Manager not to build it. (Right-click on the Solution, and select Configuration Management)
As far as I know ctrl + shift + b is by default bound to BuildSolution, so that would be why all your projects are being build. i'm not really sure what else you could use except for rightclicking the project and pressing build :)
You might want to check in Tools>Option>Projects and Solutions and check if your option is set to Only Build startup project and dependencies instead of all the solution.
Or instead of using ctrl+shirt+b you should simply press F6 on the project you want to build :)
You can use shift+F6 to build just the current project.
While not directly answering my question: "is there a tool that'll work this out for me?", I found the specific problem by using SysInternals Process Monitor:
The project was configured with /analyze, which requires Visual Studio Team Edition, but the version on this PC is Visual Studio Professional, which doesn't support it. Unfortunately, there appears to be a bug in Visual Studio, where it thinks that the .pchast file should be created, even though it has no way to do so. I've raised this on Connect.
I think I might write a macro for Visual Studio Professional that, if /analyze is turned on, simply creates an empty .pchast file at the end of the build...

Finding errors / warnings in Visual Studio

I have experienced an annoying issue with Visual Studio 2005... sometimes when I rebuild, and even if I do a Rebuild Solution, it will come back with no errors or warnings, but then when I later edit another code file, even without changing it, and rebuild, it will find an error or warning in that other file. Clearly, the earlier Rebuild Solution did not recompile that file! How can I force VS to completely recompile every file?
I've seen this happen before when you have multiple projects in your solution and the references get mixed up.
Say you have four projects in your solution, Common, Business, Data, and UI. Assume that Common is referenced by the other three projects.
What we want is for Common to be a "project reference" from the other three projects - they'll then pick up their copy from the build output directory of Common.
But, sometimes, one of the projects will get it's reference mixed up. Say, in this case, that UI starts referencing the copy of Common in the build output directory of Data. Now, any change that compiles "UI" without also compiling "Data" will result in two, possibly incompatible, versions of "Common" being a dependency of UI.
Another scenario is where the reference is to a binary, such as from a "lib" directory. Then, one of the projects ends up referring to a build output location instead of lib.
I don't know what causes this - but I see it all the time, unfortunately.
The fix is to go through the references of each project and find the one (or more) that point to the wrong place.
It might help to clean the solution prior to rebuilding -- right click on the solution in the Solution Explorer and choose "clean solution" -- this deletes temporary files and is supposed to clear out the bin and obj folders, so everything is rebuilt.
I'm with Guy Starbuck here, but would add that Rebuild Solution is supposed to do a Clean Solution followed by Build Solution, which should, then, have solved your issue to begin with. But VS 2005 can be terrible in this regard. Sometimes it just starts working after several rebuilds. If upgrading to 2008 isn't an option, consider manually clearing the bin folder.
Is this related to the Configuration Manager? There you can select which projects in your solution build. Not sure if this helps.
Depending on the types of warnings it is not possible if I recall correctly.
For example, warning messages for XHTML compliance are ONLY displayed when the file is open. You might check the tolerance settings inside VS to see if you can change it.
This sounds strange - Rebuild should build everything regardless of changes and Build should only build things that have changed.
The behaviour you've described should only happen if you have modified something that is referenced by the unchanged file so that it is now incorrect.

Resources