/MT vs. /MD on MSVC

1,243 views
Skip to first unread message

kenton

unread,
Apr 21, 2009, 6:56:14 PM4/21/09
to Google C++ Testing Framework
I'm trying to integrate the Protocol Buffers release with the latest
version of gtest. My goal is to allow the latest release of gtest to
be dropped into the protobuf package verbatim and have everything just
work.

One problem I've run into is with MSVC. gtest's project files
currently use /MT (statically-linked C runtime library) which makes
them incompatible with any project using /MD (dynamically-linked
runtime). Currently, libprotobuf is linked with /MD. I don't
remember making this decision consciously so I suspect that /MD is the
default for new projects. No protobuf user has ever mentioned having
a problem with libprotobuf using /MD as far as I know, but I see
several posts to this mailing list suggesting that /MT has caused
linking problems for gtest users.

So the question is, why does gtest use /MT? Was this an arbitrary
choice or is there some justification behind it? To me /MD seems like
the appropriate default but I don't do much Windows programming so I
could easily be wrong. I could pretty easily change libprotobuf to /
MT but I'm hoping there's a good reason to do so, other than just to
match gtest.

Zhanyong Wan (λx.x x)

unread,
Apr 21, 2009, 7:45:47 PM4/21/09
to kenton, Vlad Losev, Google C++ Testing Framework
Hi Kenton,

Here is what I know:

- gtest's VC projects were created in VS 2003 (VC 7.1), the lowest VS
version gtest supports. Users of newer VS versions can easily
upgrade the projects before using them. If we create the projects
in VS 2005 instead, they won't be usable by users of VS 2003.

- A VS 2003 project by default uses /ML (single-threaded, statically
linked libc). We didn't change the default, thinking it is more
likely to match what a user uses.

- A VS 2005 project by default uses /MD (multi-threaded, DLL).

- When you upgrade a VS 2003 project to the VS 2005 format, /ML is
automatically changed to /MT, as it seems that /ML is deprecated in
VS 2005.

- /MD requires MSVCR71.DLL or MSVCR80.DLL to be available at run time.
In contrast, /ML and /MT produce self-contained programs.

I think the root problem is that MS changed the default settings when
going from VS 2003 to VS 2005.

If we can pick freely (i.e. ignoring what the user uses), /MT seems a
safer default than /MD, as it doesn't rely on MSVCR*.DLL at run time.
Usually this doesn't matter as that DLL is installed when you install
VS. However, if you copy a test built with /MD to another machine
where VS is not installed (or the version of VS is not expected), my
understanding is that it will not run. This can lead to surprises and
headache. It may not be a common scenario. Still, it would be nice
not to have to worry about that.

Since you got /MD by default, I suspect you are not using VS 2003. Is
that so? Do you need to support users of VS 2003?

Whichever flag we pick, it's gonna conflict with some users. I think
we'll just have to document clearly that the user must make sure the
same flag is used in the projects.

Vlad, what are your thoughts on this? Thanks,

--
Zhanyong

Kenton Varda

unread,
Apr 21, 2009, 8:19:44 PM4/21/09
to Zhanyong Wan (λx.x x), Vlad Losev, Google C++ Testing Framework
Thanks, this at least explains what I encountered.  I maintain protobuf with MSVC 2008 but use a hack to back-convert the project files to MSVC 2005 before release (it turns out you just have to flip the version number).  So when I tried to compile gtest, the project files were upgraded as you describe.

There are certainly reasons why some people might prefer /MT as you describe, but there are also many reasons to prefer /MD.  In the end I think this depends on the app, which makes it highly annoying that MSVC doesn't provide any reasonable way to let the app decide which library to use.  I would argue that /MD is the better default simply because it is the MSVC default, and thus it's the flag likely to be used by people who don't know or don't care about this setting.  Those who do know and care will be able to figure out how to change the setting as needed.

That said, since you are committed to supporting MSVC 2003 it seems like changing the default for gtest is not a viable option, so I have to decide if it's more trouble for me to use /MT for protobuf or to somehow automatically munge the gtest project files.

2009/4/21 Zhanyong Wan (λx.x x) <w...@google.com>

Vlad Losev

unread,
Apr 21, 2009, 8:50:33 PM4/21/09
to Zhanyong Wan (λx.x x), kenton, Google C++ Testing Framework
2009/4/21 Zhanyong Wan (λx.x x) <w...@google.com>
Hi Kenton,

Changing the setting in gtest.vcproj will be beneficial for users of VS 2005 and later since it is a default for their projects. It will create problems for VS 2003 users, sure, but the users of VS 2005+ now constitute an overwhelming amount of our total VC userbase, I believe. So I have no problems with changing the default.

WRT the documentation, we have an FAQ entry which explains the problem and the possible solutions. Do you think it needs further promotion?

Regards,
Vlad.

Kenton Varda

unread,
Apr 21, 2009, 9:04:14 PM4/21/09
to Vlad Losev, Zhanyong Wan (λx.x x), Google C++ Testing Framework
2009/4/21 Vlad Losev <vl...@google.com>

Changing the setting in gtest.vcproj will be beneficial for users of VS 2005 and later since it is a default for their projects. It will create problems for VS 2003 users, sure, but the users of VS 2005+ now constitute an overwhelming amount of our total VC userbase, I believe. So I have no problems with changing the default.

That would be helpful to me.  When could you make this change?
 
WRT the documentation, we have an FAQ entry which explains the problem and the possible solutions. Do you think it needs further promotion?

I'm not sure.  Personally I figured out the problem easily by comparing settings between the projects, but not everyone would think to do that.

Vlad Losev

unread,
Apr 21, 2009, 9:21:45 PM4/21/09
to Kenton Varda, Zhanyong Wan (λx.x x), Google C++ Testing Framework


2009/4/21 Kenton Varda <ken...@google.com>

2009/4/21 Vlad Losev <vl...@google.com>

Changing the setting in gtest.vcproj will be beneficial for users of VS 2005 and later since it is a default for their projects. It will create problems for VS 2003 users, sure, but the users of VS 2005+ now constitute an overwhelming amount of our total VC userbase, I believe. So I have no problems with changing the default.

That would be helpful to me.  When could you make this change?
 

This will take some time since this will also require to recreate gtest.vcproj and gtest_main.vcproj so that they produce DLLs instead of static libraries, lest we end up with the 'two copies of static data' problem. Zhanyong - are you OK with that change?


 - Vlad

Kenton Varda

unread,
Apr 21, 2009, 9:25:48 PM4/21/09
to Vlad Losev, Zhanyong Wan (λx.x x), Google C++ Testing Framework


2009/4/21 Vlad Losev <vl...@google.com>



2009/4/21 Kenton Varda <ken...@google.com>

2009/4/21 Vlad Losev <vl...@google.com>

Changing the setting in gtest.vcproj will be beneficial for users of VS 2005 and later since it is a default for their projects. It will create problems for VS 2003 users, sure, but the users of VS 2005+ now constitute an overwhelming amount of our total VC userbase, I believe. So I have no problems with changing the default.

That would be helpful to me.  When could you make this change?
 

This will take some time since this will also require to recreate gtest.vcproj and gtest_main.vcproj so that they produce DLLs instead of static libraries, lest we end up with the 'two copies of static data' problem. Zhanyong - are you OK with that change?

Is that true?  The protobuf project files produce static libraries by default but use /MD.  I don't know of any problem with this.  Frankly I'd recommend against producing DLLs due to the myriad problems with using STL in a DLL's interface on MSVC.

And what do you mean by "recreate"?  These are just options in the project config that you can toggle freely.

Kenton Varda

unread,
Apr 21, 2009, 9:33:22 PM4/21/09
to Vlad Losev, Zhanyong Wan (λx.x x), Google C++ Testing Framework
BTW, for the time being I'm using this command to auto-convert the gtest project files to be compatible with mine:

  sed -i -e 's/RuntimeLibrary="5"/RuntimeLibrary="3"/g;
             s/RuntimeLibrary="4"/RuntimeLibrary="2"/g;' gtest/msvc/*.vcproj

One of those conversions is for debug and one is for release, but I'm not sure which is which.  Anyway, it works.  I did not change the projects to produce DLLs themselves.

Zhanyong Wan (λx.x x)

unread,
Apr 22, 2009, 1:44:44 AM4/22/09
to Kenton Varda, Vlad Losev, Google C++ Testing Framework
2009/4/21 Kenton Varda <ken...@google.com>:

> There are certainly reasons why some people might prefer /MT as you
> describe, but there are also many reasons to prefer /MD.  In the end I think
> this depends on the app,

Exactly.

> which makes it highly annoying that MSVC doesn't
> provide any reasonable way to let the app decide which library to use.  I

Agreed.

> would argue that /MD is the better default simply because it is the MSVC
> default, and thus it's the flag likely to be used by people who don't know
> or don't care about this setting.

/MD is a better default for users of VS 2005+. /ML is a better
default for users of VS 2003. It sucks that MS changed the default


from VS 2003 to VS 2005.

> Those who do know and care will be able


> to figure out how to change the setting as needed.

Agreed.

> That said, since you are committed to supporting MSVC 2003 it seems like
> changing the default for gtest is not a viable option, so I have to decide

We (you, I, Vlad, and the users) can discuss it.

> if it's more trouble for me to use /MT for protobuf or to somehow
> automatically munge the gtest project files.

If we decide to not change the gtest default and if your primary users
use VS 2005+, I suggest the latter as it is more convenient for your
users.

--
Zhanyong

Zhanyong Wan (λx.x x)

unread,
Apr 22, 2009, 1:51:35 AM4/22/09
to Vlad Losev, kenton, Google C++ Testing Framework
2009/4/21 Vlad Losev <vl...@google.com>:

>
> Changing the setting in gtest.vcproj will be beneficial for users of VS 2005
> and later since it is a default for their projects. It will create problems
> for VS 2003 users, sure, but the users of VS 2005+ now constitute an
> overwhelming amount of our total VC userbase, I believe. So I have no
> problems with changing the default.

I agree it's probably the right thing for the long term. Just to make
it clear to everybody: this will be a *breaking* change. If you use
Visual Studio and get the next version of gtest, which uses /MD,
you'll have to either manually change the gtest VC projects back to
/ML or /MT, or manually change your own VC projects from /ML or /MT to
/MD. Not an insurmountable problem, but it will require the user to
do some work and I'd like to make it clear up-front.

Does anyone have any concern? Thanks,

--
Zhanyong

Zhanyong Wan (λx.x x)

unread,
Apr 22, 2009, 2:00:12 AM4/22/09
to Vlad Losev, Kenton Varda, Google C++ Testing Framework
2009/4/21 Vlad Losev <vl...@google.com>:

> This will take some time since this will also require to recreate
> gtest.vcproj and gtest_main.vcproj so that they produce DLLs instead of
> static libraries, lest we end up with the 'two copies of static data'
> problem. Zhanyong - are you OK with that change?

I'm wary about producing DLLs since that will make the built tests
even less self-contained. Could you give an example of what you mean
by the "two copies of static data" problem? What does a user need to
do in order to run into it? How likely is that? Thanks,

--
Zhanyong

Vlad Losev

unread,
Apr 22, 2009, 2:00:53 AM4/22/09
to Kenton Varda, Zhanyong Wan (λx.x x), Google C++ Testing Framework
2009/4/21 Kenton Varda <ken...@google.com>


2009/4/21 Vlad Losev <vl...@google.com>


2009/4/21 Kenton Varda <ken...@google.com>

2009/4/21 Vlad Losev <vl...@google.com>

Changing the setting in gtest.vcproj will be beneficial for users of VS 2005 and later since it is a default for their projects. It will create problems for VS 2003 users, sure, but the users of VS 2005+ now constitute an overwhelming amount of our total VC userbase, I believe. So I have no problems with changing the default.

That would be helpful to me.  When could you make this change?
 

This will take some time since this will also require to recreate gtest.vcproj and gtest_main.vcproj so that they produce DLLs instead of static libraries, lest we end up with the 'two copies of static data' problem. Zhanyong - are you OK with that change?

Is that true?  The protobuf project files produce static libraries by default but use /MD.  I don't know of any problem with this.  Frankly I'd recommend against producing DLLs due to the myriad problems with using STL in a DLL's interface on MSVC.

Oops, my mistake. DLLs do work from a static library; it's the other way around that is problematic.


And what do you mean by "recreate"?  These are just options in the project config that you can toggle freely.

Well, if one has to change the project type from the static library to the DLL, one needs to virtually create a new project. But you are right, we don't need that in this case.

- Vlad

Kenton Varda

unread,
Apr 22, 2009, 2:18:56 AM4/22/09
to Vlad Losev, Zhanyong Wan (λx.x x), Google C++ Testing Framework
2009/4/21 Vlad Losev <vl...@google.com>



And what do you mean by "recreate"?  These are just options in the project config that you can toggle freely.

Well, if one has to change the project type from the static library to the DLL, one needs to virtually create a new project. But you are right, we don't need that in this case.

It's a moot point, but you can actually switch between building static vs. dynamic libraries in the project properties dialog, at least in VS2008.  No need to create a new project.
Reply all
Reply to author
Forward
0 new messages