-5

I use Visual Studio 2017 (but applies to any version from 2010+) and I've been trying to come up with a way to organize my Debug/Release libraries in such a way as to avoid all these linking errors we get, when mixing different versions of the Runtime libraries. My goal seems simple, conceptually, but I have not yet figured out a way to achieve all I want.

Here's what I have, and what I'd like to do:


Common Libraries:
ComLib1
ComLib2
...


Exe1:
ComLib1
ComLib2
...
Exe1Lib1
Exe1Lib2
...
Exe1


Exe2:
ComLib1
ComLib2
...
Exe2Lib1
Exe2Lib2
...
Exe2


So 2 different executable, using a set of common libraries and Exe-specific libraries.

I want to create 4 different build configurations.

Cfg1:
This would contain debugging info/non-optimized code for all libraries, including the Common Libraries.

Cfg2:
This would contain debugging info/non-optimized code for all Exe-specific libraries, but NOT for the Common Libraries.

Cfg3:
This would contain a combination of debugging info/non-optimized code libraries for some libraries, and non-debugging info/optimized libraries for the remaining ones.

Cfg4:
You guessed it. This would contain non-debugging info and optimized code for all.

My first attempt was to basically create 2 sets of binaries for each library; one compiled in Debug Mode (with /MTd /Od) and another one compiled in Release Mode with (/MT /O2). Then pick one or the other version in my various configurations. This was fine for Cfg1 & Cfg4 (since all Runtime libraries are consistent throughout), but ran into those those linking errors for Cfg2 & Cfg3.

I understand why I get these errors. I'm just not sure how one goes about resolving these things, in what I would think would be a common scenario. Maybe Cfg3 is uncommon, but I would think Cfg1,2 & 4 are.

Thanks for your inputs.


EDIT
I didn't really think I needed to add this information because I wanted to keep my question short(er). But if it can help clarify my goal, I'll add this up.

This is for a Realtime simulator. I just can't run every single library in a typical Debug configuration, as I would not be able to maintain Realtime. I seldom need to Debug the Common Libraries because they're mostly related to Server/IO tasks. The Exe libs mostly contain math/thermodynamics and is where I mostly spend my time. However, 1 Exe lib contains reactor neutronics, which involved heavy calculations. We typically treat that one as a black-box (cryptic vendor-provided code) and I almost always want to run it using Optimized code (typical Release settings).

ThermoX
  • 277
  • 3
  • 11
  • I had to read to the bottom to get the slightest hint of what your toolchain is likely to be. I'm going to add a visual Studio tag in a few moments, but this is something that should come up in the first paragraph or so of a question like this. – user4581301 Oct 04 '18 at 20:53
  • Thanks for the constructive feedback. I'm ok with people down voting. I just hate it when they do it without an explanation. No matter who the target is. – ThermoX Oct 04 '18 at 21:21
  • Funny thing is I did not and still haven't downvoted. I don't know Visual Studio nearly well enough to be able to rate this question as good or bad. – user4581301 Oct 04 '18 at 21:39
  • Cfg2 and Cfg3 might work, but can result in undefined behavior, and are extremely poorly supported (as you are seeing). I would highly recommend avoiding these configurations unless absolutely necessary for acceptable performance when debugging your code. – zzxyz Oct 06 '18 at 00:18
  • See: https://stackoverflow.com/questions/11658915/mixing-debug-and-release-library-binary-bad-practice – zzxyz Oct 06 '18 at 00:22
  • @zzxyz I did see a lot of comments about mixing configurations. Maybe that's why people have down voted my question, thinking I hadn't done the research. But I really do need this type of configuration. This is for Realtime simulation and I just can't run everything in Debug for very long and maintain Realtime. But I also need to Debug the Exe libs during development. I provided an answer that seems to work below. – ThermoX Oct 06 '18 at 12:23

3 Answers3

1

You can not use different runtime libraries in the same process without some special considerations (e.g. using a DLL or so with no CRT object in the interface to make them entirely seperate) without either link errors or risking runtime issues if CRT objects are passed between.

You can mix most of the general optimisation options within a module with the notable exception with link time code generation that must be the same for all objects. The release runtime libraries are also generally usable for debugging as long as your own code is not optimised.

To easily switch you will want a solution configuration for each case you want (so 4). You can make one project configuration be used by multiple solution configurations if you do not want some that are duplicates but it must follow the previously mentioned limitations, and can confuse things like output directory. You can also use property sheets to share settings between multiple projects and configurations.

Fire Lancer
  • 29,364
  • 31
  • 116
  • 182
  • I actually do use Property Sheets already. I've stripped most of the local project settings and inherit them from my Property Sheets, instead. That's where I want to define my 4 configurations because they would be identical between Exe1 and Exe2, in example above. I guess my issue is to figure out which configuration should use which Runtime. I tend to associate Optimizing options (/O2) with Release Runtimes and non-optimized options (/Od) with Debug Runtimes and that's how I originally built my setup. It seems odd to call a configuration Debug and have it use a Release Runtime. – ThermoX Oct 04 '18 at 23:54
  • 1
    I just think of the debug CRT as extra debugging. It is not needed to debug many issues in a module, you can still see the values of strings, vectors, etc. and makes the overall program very fast. – Fire Lancer Oct 05 '18 at 19:11
0

I've done similar using predefined macros for either the output directory path or the target filename.
For example, I use $(Platform)_$(Configuration) which expands to Win32_Debug or Win32_Release.

You can use environment variables as well. I haven't tried using preprocessor macros yet.

Search the internet for "MSDN Visual Studio predefined macros $(Platform)".

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • Thanks for your inputs. I'm familiar with those Visual Studio macros, as I use them quite a bit in my Property Sheets. But I'm not sure this addresses my question. Maybe my question isn't clear enough and that's why I'm getting all these down votes. – ThermoX Oct 05 '18 at 11:01
-1

So this is how I ended up getting what I wanted.

Assuming I'm using the static Runtime libraries, I think I'll keep the typical Debug/Release (/MTd and /MT, respectively) libraries for my Common Libraries and create 3 sets of libraries for my Exe's:

Exe1Lib1Release: Typical Release Configuration
Exe1Lib1Debug: Typical Debug Configuration
Exe1Lib1DebugMT: Non-optimized code with debugging info, but using the MT Runtime libraries

Cfg1:
Will use the typical Debug libraries all around

Cfg2 & Cfg3:
Will use the typical Release libraries for the Common Libraries, and the Exe1Lib1DebugMT for the Exe's libraries

Cfg4:
Will use the typical Release libraries all around.


EDIT
Actually, Cfg2 & Cfg3 settings are more accurately represented by:

Cfg2:
Will use the typical Release libraries for the Common Libraries, and the Exe1Lib1DebugMT for the Exe's libraries

Cfg3:
Will use the typical Release libraries for the Common Libraries, and a combination of Release and Exe1Lib1DebugMT for the Exe's libraries

ThermoX
  • 277
  • 3
  • 11
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - [From Review](/review/low-quality-posts/21052821) – Alex Kulinkovich Oct 06 '18 at 10:13
  • @Alex.K I'm not sure why you say this. I actually ended up doing exactly that and it fulfilled all my requirements mentioned in my original post. Maybe I didn't express those requirements clearly enough or provided enough details for people to understand them, but what I did very much gives me what I wanted to do. – ThermoX Oct 06 '18 at 12:28
  • @Alex.K Well, to be more accurate. I'm now getting clean builds on all 4 configurations without having to use /NODEFAULTLIB. The Realtime program seems to work fine on all 4 configurations as well. But I haven't done a huge amount of tests yet and I haven't attempted to put breakpoints in those various libraries to see if I get the debugging info I was hoping for. – ThermoX Oct 06 '18 at 12:46