allquixotic
allquixotic

Reputation: 1569

Microsoft C++ Library Symbol Linkage At Build Time

Using Visual Studio C++ 2008 Express:

I am trying to perform the final link step in a build compiled as follows:

Am I trying to set up an impossible situation with this build, or am I just doing something wrong? If this can't work at all in theory, let me know. Otherwise, please let me know what diagnostics I could try to determine why the C++ library symbols are not available to foo.lib during the final link step.

Edit: More specific information: foo.lib is LLVM 3.1 and bar.dll is the libgl-gdi (llvmpipe) build of Mesa from the master branch (the goal is to produce opengl32.dll that runs on llvmpipe). I have satisfied all the build dependencies as follows:

I have also customized the build for each project as appropriate to set environment variables and ensure that they are consistently using only the /MD switch and not /MT or some other switch for selecting a wrong C runtime library.

Upvotes: 2

Views: 1000

Answers (3)

Adrian McCarthy
Adrian McCarthy

Reputation: 48019

Here's a working sample that does what you're trying to do.

foo.h:

#ifndef FOO_H
#define FOO_H

extern void print_foo();

#endif

foo.cpp:

#include "foo.h"

#include <iostream>

void print_foo() {
  std::cout << "foo" << std::endl;
}

Build foo.cpp into a static library that will depend on the dynamic run-time libraries:

cl /c /MD /EHsc foo.cpp
lib foo.obj

bar.h:

#ifndef BAR_H
#define BAR_H

#ifdef BAR_DLL
#define BARAPI __declspec(dllexport)
#else
#define BARAPI __declspec(dllimport)
#endif

BARAPI void print_bar();

#endif

bar.cpp:

#include "bar.h"

#include <iostream>
#include "foo.h"

BARAPI void print_bar() {
  std::cout << "bar" << std::endl;
  print_foo();
}

Build bar.cpp into a DLL that pulls in code from foo.lib and depends in the dynamic runtime libraries:

cl /c /MD /EHsc /DBAR_DLL bar.cpp
link /DLL bar.obj foo.lib

And a simple main.cpp to show that it works:

#include "bar.h"

int main() {
  print_bar();
  return 0;
}

Build it like this:

cl /c /MD /EHsc main.cpp
link main.obj bar.lib

(The runtime libraries should come in automatically because the /MD options should have tagged the object files as needing the dynamic runtime libraries.)

main.exe output:

bar
foo

Upvotes: 0

YePhIcK
YePhIcK

Reputation: 5866

From the MSDN help:

Defines _MT and _DLL so that both multithread- and DLL-specific versions of the run-time routines are selected from the standard .h files. This option also causes the compiler to place the library name MSVCRT.lib into the .obj file. Applications compiled with this option are statically linked to MSVCRT.lib. This library provides a layer of code that allows the linker to resolve external references. The actual working code is contained in MSVCR71.DLL, which must be available at run time to applications linked with MSVCRT.lib.

When /MD is used with _STATIC_CPPLIB defined (/D_STATIC_CPPLIB) it will cause the application to link with the static multithread Standard C++ Library (libcpmt.lib) instead of the dynamic version (msvcprt.lib) while still dynamically linking to the main CRT via msvcrt.lib.

More specifically - this excerpt: "Applications compiled with this option are statically linked to MSVCRT.lib"

In other words - you need to link your foo.lib to msvcrt.lib.

Upvotes: 1

cppguy
cppguy

Reputation: 3713

This is a common point of confusion with visual studio projects.

/MD doesn't build a static library. That is a flag that can be used with any binary output from visual studio (lib, dll, exe). It merely means you're telling your binary to use the static CRT (C runtime). This is, in the common case, the wrong choice and you will get link issues when linking into applications or DLL's that do NOT statically link the CRT (using the DYNAMIC CRT).

Have a look here for more information:

http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=vs.71).aspx

There should be a setting under the project settings under Configuration Properties/General/Configuration type. That should be what you're using to determine what kind of binary you're building

Upvotes: 0

Related Questions