Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / Linker error; unresolved external; symbol already defined; libcmt.lib & co.; deploying the game

Author
Message
tempicek
16
Years of Service
User Offline
Joined: 27th Nov 2007
Location: Prague
Posted: 3rd Jan 2008 15:08 Edited at: 3rd Jan 2008 15:34
Hello,

I realized that there are many GDK users solving problems with linking C runtime without any idead what it is all about. The problem is that to some extent, you have to solve each problem individually, which is hardly possible if you don't know what it actually means. So I decided to summarize the problem for any followers to help them understand it and solve it on their own.

How does it look like? Well, in Visual Studio you try to compile your project and see lines like these in the Output window:
Case 1

Case 2


For an untrained eye, there is some unknown problem in a function you have never heard of, which is used in a file you have never heard of, which is part of a module you have never heard of

We will get into it, but we need some background first. Most beginners consider the error above to be a compiler problem. It's not! It's a linker problem and most often you have caused it to happen. And you can shout out that the same code is working for some other guy and that it's crappy and bloody stupid, but it's not, actually it's pretty smart, just a bit more complex than you would think.

The problem is that nowadays with powerful IDE's like MS Visual Studio you might think that programming is just writing code in language specific syntax. But it's not and there are bits of knowledge you need to gather too. A build process (a process of making an executable code out of your project/source files) have several steps and each step is simply performed by running some particular tool/program with particular arguments. Once you needed to know all the arguments and write them to so called makefile which drives the build process. In advanced IDE like MSVS you don't need to know those tools and their arguments, but you should know where and how to configure them instead. That's where the project settings come in.

Two main parts of the build process are performed by a compiler and linker. While compiler translates pieces of your source code to pieces of machine specific code, the linker joins the pieces and links them together to one final output, which is the executable (od library) you are up to. Correct compiler errors is mostly very simple, you only need to know the language (C++ here) syntax. Persuade linker to do what you need can be sometimes bit more complex as you need more knowledge about the process. However, the principle is quite similar to what compiler does. Where you need to tell compiler to read some declarations from some particular header file (using #include "header.h") so that compiler would know the identifier, you also need to tell the linker where it can find the appropriate symbol, i.e. the compiled code. You do this in "Project Settings | Linker | Input | Additional dependencies". There you add the name of the library (mylibrary.lib) which contains the code of a function you are going to use.

When someone builds a code as a static (.lib) or dynamic (.dll) library, you can reuse the code in your application by calling the routines stored in the library. The difference is that while the code from static library is linked to your executable by linker during build process, a dynamic library code is linked at runtime and your code only contains references (addresses) to the particular DLL (This is useful when more applications use the same code as you don't need to add the code to every application - they can share a single system version.). As a result, you always need to define static libraries only as an input for the linker. (Another thing is, that for each dynamic library there is always a static library which performs the dynamic linking in runtime. But don't do this too complex now. )

"Smartass, we know these things!" Maybe you do, maybe someone not. Now we can return back to the original problem. Lets translate the Case 1 to some readable form:
StaticLibrary.lib(ObjectFile.obj) : error LNK2005: DuplicateSymbol already defined in StaticLibrary2.lib(ObjectFile2.obj)

The message says, that some symbol (e.g. a function) is already linked to your executable and you are trying to link it again. In our case it's a DuplicateSymbol defined in StaticLibrary, which has already been linked in from StaticLibrary2. It's because both static libraries contain a symbol of the same name. That's not allowed. We will see later why this can happen.

Case 2 says:
StaticLibrary.lib(ObjectFile.obj) : error LNK2001: unresolved external symbol "SymbolDeclaration" (SymbolName)

This says that some symbol (e.g. a function) which is declared as 'SymbolDeclaration' in your language syntax and used by some function in StaticLibrary is not has not been found in any linker input file. (Ignore the SymbolName, it's a name mangling performed by the C++ linker. It will be complex enough without investigating this.)

Whereas case 2 came up because you forget to add some static library to the list of dependencies (as mentioned before) and can be easily fixed, case 1 can occur because you linked incompatible libraries together. (Again, it can be more complex, but in most cases mentioned on these forums it's just the C runtime which makes troubles.)

Now, thing about the difference between debug and release code. In debug code you write unnecessary checks, error/debug outputs and so on. Simply you do a lot of stuff which is not needed, or even wanted in release code (makes it longer and slower). So, you write a library which someone can use and you need to decide - offer a debug version so that he can debug the code more easily, or release version so it is faster? The answer is straigtforward - offer both. If you offer both libraries, one can choose which one to use in each build (debug/release/whatever). But here's the problem, all the pairs of symbols in both libraries have the same name. How to solve it? Easily - you have separate project settings for debug and release build. Each build picks up its library.

"Where's the problem then?" The problem is that many programming beginners doesn't realize that while they are using standard functions like "printf", even these functions need to be defined somewhere. So in (almost) any program you need to add some static library to the linker dependencies list. You don't do that, do you? Still it's working, right. Why? Because these standrad functions are actually so common, that Visual C++ IDE is adding them automatically to the linker input.

"Case solved then?" Hardly. MSVS do this automatically, but only for the initial project setup if you create a project with a wizard (which you always do). If you change some project settings, it's possible that you need to change the linker input too. It's because there are several libraries implementing those standrad functions and they differ. You use one for debug build, another one for release build. You can link it statically or use dynamic libraries. In older versions of Visual C++ you were able to choose between single- and multi-threaded versions. In any case, you must assure that you use only one of them, or else you get the error in case 1. Some people are smart enough to realize, that using /NODEFAULTLIB linker option (does the same as "Proj.sets. | Linker | Input | Ignore All Default Libraries = Yes") prevents VC++ from adding these standard libraries to linker input. However, they are often not smart enough to realize, that when they does this, they must care about the linker input themself. That's when they obtain the error message in case 2.

Which runtime library you are actually using is defined in "Project sets. | C/C++ | Code Generation | Runtime Library" or by compiler switches /MT*, /MD* or deprecated /ML*. You should set the linker input according to this. However, with GDK it's more complex again, since they don't offer debug versions of their libraries. Therefore the code you are working with is always using release version of runtime libraries. Since their libraries expect release version of standard libraries, you have to link against release version too. And since you have to link against one version only, you can not use debug version of runtime libraries. A pitty, isn't it? (Well, ok, we could make it more complex again and find our way out of this, but that would only spread fear and confusion and practically help to nobody. )

So, to summarize it:
1) you need to choose proper runtime usage (either DLL or static version, but release)
2) properly set the linker dependencies, or let the VC++ do it automatically and rather set the "exceptions" to the linker input, which are to be set in "Proj.sets. | Linker | Input | Ignore Specific Library"

As for myself, I enjoy the way of precise configuration, so I set the "/NODEFAULTLIB" and then set the input accordingly to my setting.

As a side note - don't forget that if you are working on more projects in one solution where one of these projects is dependent on others (the one is .exe and others are libraries), you should use the same Runtime libraries for all of them (for a particular build configuration).

I chose these links where you can find precise info of the setting I was slightly talking about (I was just explaining the background, you should read that after this!):
Choose appropriate runtime library: http://msdn2.microsoft.com/en-us/library/aa278396(VS.60).aspx
Which libraries to ignore for particular setting: http://msdn2.microsoft.com/en-us/library/aa267384(VS.60).aspx
What are those libraries (with samples): http://support.microsoft.com/kb/154753




Finally, I would like to discuss the topic of deploying your game. The easier way is when you choose the static version of runtime libraries. In that case the code of standard functions is linked into your executable file and it's not dependent on external DLLs installed (side-by-side) on the target machine. However, if you for some reason choose dynamic linkage of the runtime, you have to ensure those dynamic libraries are available on user's machine. There are several ways how to ensure this:

1) Install the C runtime redist during a setup process of your game. This is easy and efficient, especially if you have Pro version of Visual Studio where your Setup project can ensure this for you.

2) If you don't have an installer or you don't want it to be too big (small archive for download from web), you can link to this page: http://www.microsoft.com/downloads/details.aspx?familyid=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&displaylang=en, where anyone can download the installer for VC++ 2008 runtime redist (you can find similar download pages for VC++ 2005 and older). However, it becomes a bit more complex then because you need to provide a valid link depending on whether the user have x86 or x64 operating system installed.

3) Finally you can add those libraries to your archive without installing the runtime redist. This is a valid way of linking and does not broke any license. You get a bigger installer than in case (2) and the user can end up with tens of these libraries on his machine if every application comes with this (it breaks the idea of dynamic linkage in some way). The advantage is that you don't have to create an installer and the user doesn't have a clue that such a thing is being copied to his machine (in contrast to (1) and (2) where the runtime redist installer asks the user for permission). Moreover it's more resistant to problems with user access rights. This way is pretty easy, but can sometimes bring some pain with inconsistent side-by-side (SxS) library linking and unresolved externals in runtime (not during build), which is much harder to solve as the code ran on machine to which you don't have access. In these cases it is most useful to use a tool like Dependency Walker (Depends.exe in your MSVS install dir) which tells you which libraries your application needs. However I'm not gonna talk about this as it could make a whole separate article


No matter which way you choose to use the runtime library, you always have to install the DX9.0c redist (August 2007 version these days, but will probably change in the future) on the target machine. It should be noted, that it's not the standard DirectX 9.0c package which is already installed on all XP SP2 and Vista platforms, and it is not the DX SDK which you have to install on the development machine (though the runtime is a part of it). If you were curious what it is, it's a package of advanced useful functions (used by GDK) provided by Microsoft. Most of these functions are contained in dynamic library d3dx9_35.dll (for august version of DX SDK, other SDKs uses different number). Again there are several ways how to ensure this component is installed on the user's machine:

1) Use your setup program and add a custom step for installing the package you distribute with your game. If you chose "Redist" to be installed on your machine when you were running the DX SDK installer, the package is already on your computer and you can find it in [DX SDK]Redist folder. This setup package can be freely distributed with your game, however, in contrast with C runtime redist, you can't distribute the DLLs directly. You must distribute only the setup package which contains EULA etc. Doing this other way you are breaking the license. The package has about 70 MB and will likely grow in the future, but it's possible to distribute just a portion of the package you actually use in your project. (I won't go into details now; ask if you are interested.)

2) Offer a link to the redist on the MS's web: http://www.microsoft.com/downloads/details.aspx?FamilyID=cb7397f3-0949-487b-9247-8fee451bf952&displaylang=en. Fortunately, there are both versions included in the package - x86 and x64. Unfortunately, the package is rather big. Also don't forget that this applies to GDK version which uses August 2007 DX redist, this will probably change in the future and the link won't be valid. However, for a game which you make today with actual version of GDK, this is true and remain true forever (so you don't have to be afraid that it won't run later). This way is useful for users which don't have internet connection on the machine where they are gonna play your game.

3) Offer a link to redist web setup: http://www.microsoft.com/downloads/details.aspx?FamilyId=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3&displaylang=en. The difference is that the web setup precisely discovers what your system needs and what is missing and download only the necessary parts, which means a lot faster download. Another difference is that this link always points to the last version of DX redist. That's a good behavior though as the newer version contains all the older components too.


The topic is hardly depleted , but a bit exhaustive to summarize . I hope this will help someone and prevent posting the same questions on this topic over and over. My apologize to those who are more confused than before.

Have a nice day

//rem
Pixel Perfect
17
Years of Service
User Offline
Joined: 21st Feb 2007
Location: UK
Posted: 3rd Jan 2008 16:01
Good info tempicek, takes some reading but should be helpful for a lot of users.

I had similar problems when I first started using C++2005 Express and had to work my way through the Microsoft C++ Runtime Library Info till I understood what I was doing.

I really wish TGC would provide a debug version of the library, as they did with the the version I bought last year!

No matter how good your code is, someone will improve on it
jason p sage
16
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 3rd Jan 2008 16:28
Good Info - and nice of you to supply so many valid links that are not ALWAYS ez to find!

m0ng00se
16
Years of Service
User Offline
Joined: 2nd Dec 2007
Location:
Posted: 3rd Jan 2008 23:25
Well I think Tempicek deserves a medal or some award for going to all that trouble to help us out because I'm not even going to pretend that I knew all that stuff about libraries. Sure I knew the vague theory but actually implementing it on a daily basis is not something I've been doing well lately.

I tend to build a lot of small apps to test various things so I have code snippets everywhere, then people give me sample code that I modify etc and when I start combining all this code I do get a lot of linker errors. Just lately anyway with GDK stuff.

Tempicek you obviously know your stuff so I have a few questions for you about what you wrote. Certainly not disagreeing, just asking for even more detailed info. First I'll go read those links you provided then I'll get back to you. Thanx for going to the time and trouble to provide the information.

-m0ng00se
m0ng00se
16
Years of Service
User Offline
Joined: 2nd Dec 2007
Location:
Posted: 3rd Jan 2008 23:43
Okay, first a question about GDK. You correctly say it does not come with debug libraries and it requires release libraries or I get multiple defined linker objects.

Yet I obviously need to debug my code. I live in my debugger at the moment. So how specifically do I set up my IDE so I can still debug properly. Examples follow:

By default GDK requires that libcmtd be ignored. This gives me 17 linker errors like this:

strings.obj : error LNK2001: unresolved external symbol __CrtDbgReportW

Because my AI code uses that library for debugging. If I don't ignore that library I get 9 Linker errors as follows:

libcmt.lib(invarg.obj) : error LNK2005: __initp_misc_invarg already defined in LIBCMTD.lib(invarg.obj)

If I ignore libcmt I'm back to 17 errors. As you say I can fix the problem by using all release libraries and no debug ones but then how do I do deep debugging?

I agree with you that I've been lazy in the past. If I want to debug I turn on every debug switch I can find but that doesn't work with GDK. I've never really had to go through this before to such an extent.

Can you give me some advice please? How do I specifically tell the linker what to use so I can still debug without getting linker errors? Everytime I specifically ignore a library as per MS help instructions... I end up with a new set of either multiple defined symbols or unresolved externals.

-m0ng00se
jason p sage
16
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 4th Jan 2008 00:26
I have a dumb idea that just might help.

This is a HACK idea - it won't cure ALL your debugging woas but could be the spark to go - "You know... That MIGHT WORK!"

Make a DLL of your own - A Wrapper for a LIB that you "Trust as Solid" For Debugging purposes, and just call it statically like you would the WinAPi - you don't need to recompile that each time you write a program that uses it... make a temp "WAY TO GET BY"

Good Luck! (It just might work)

tempicek
16
Years of Service
User Offline
Joined: 27th Nov 2007
Location: Prague
Posted: 4th Jan 2008 02:02
Quote: "Can you give me some advice please? How do I specifically tell the linker what to use so I can still debug without getting linker errors?"


Well, the first thing is to follow my guide (and the links I have provided) to properly set your debug build to link successfully (be it with the release version of runtime). If you are still not able to accomplish this, try to start a new project, keep all the settings (I don't want to go thru every single item if not necessary) and just change the runtime usage ("Proj.sets. | C/C++ | Code Generation | Runtime Library") to use non-debug version (either static or dynamic). I don't understand why GDK devs chose this way or why they didn't set it up automatically, but they probably want their users to learn something

If you've done this, you will likely be glad to hear that you can debug your code even with release version of C runtime. You won't just be able to debug and/or profile calls to standard functions as the source code, asserts and validations are not included in the library. So you will likely end up sometimes with some message like "Exception occured. Source code not available, would you like to see dissasembly?" which can upset you a bit, but your code can be debugged without other limitation as long as you set up the project to include the debug information in the executable (again, I won't go thru every setting if not necessary, you can use the wizard and learn the settings one at a time).


So, to summarize - you can set it up to link against release versions of runtime libraries and still debug your code, but if the program crashes inside the standard library (because you provided wrong data), you will have harder work to find out why.

Hope this is what you are up to. Ask as needed.
tempicek
16
Years of Service
User Offline
Joined: 27th Nov 2007
Location: Prague
Posted: 4th Jan 2008 02:07
Oh, and thanks for your responses. If anyone has some comments, I am eager to hear that. We can make some sort of single FAQ out of it.
m0ng00se
16
Years of Service
User Offline
Joined: 2nd Dec 2007
Location:
Posted: 4th Jan 2008 02:54
Thankyou your suggestions worked perfectly.

I no longer have any linker errors and I can still debug.

I owe you a beer.

-m0ng00se
vletters
16
Years of Service
User Offline
Joined: 4th Jan 2008
Location:
Posted: 4th Jan 2008 19:38
Oh boy...

First of all, thank you! Secondly, I'm still feeling very unsure. I am trying to get my head around all of this and have read all the MSDN information as well as your explanation here. Unfortunately, I now only possess a vague knowledge of what is conceptually being done and even less about what I need to do in Visual Studio. Please bear with me. I am sure I've made some errors that are the essence of noob but I would greatly appreciate if one of the experts here could give me a little guidance.

I've managed to write a relatively simple program using the Dark GDK library of functions. I have read through all the tutorials and have kept the documentation open throughout. My program was debugging fine and I was eager to build it into an exe so that I could share it. I've used Visual Studio to create working .exe files before (though with Visual Basic Express Edition 2005) and assumed it would be as simple here. Unfortunately, I quickly realized there is no easy "publish" option. I have tried "Build Solution" and "Build Project" but neither has yielded a result. In fact, I now find that I cannot debug! "No Debugging Information" greets me when I try to. This is a little distressing because my program was debugging fine before I tried to build it!

Perhaps if I relay what I think I know now, can someone please help by filling in the blanks for me?

Alright, conceptually I think I have a handle on what needs to be done. Building the project creates an exe file of the code, but the project must first be compiled and then linked. Compiling takes the code in the project and "packages" or "prepares" it for being used in the executable. The linker takes this compiled code and links it to the required objects. In the case of my particular project, those objects are the standard library for C++ and the DarkGDK library (or libraries, as I see the DarkGDK.h keeps track of many). I am guessing the linker should also link the header files for these libraries to my compiled code as well.

Ok, so I can define all these things by clicking on properties for my project. From what I understand, the main things that will need to be changed are under the Linker/Input section. If I choose to ignore all default libraries, I can easily choose to include the Standard Library (the only one of the default libraries I think I am using). However, I do not know how I should properly go about including the DarkGDK libraries. In another thread tempicek argued against simply cutting and pasting the libraries and headers into the default folder, so I assume this is not the proper method.

Ultimately, my main questions are embarrassingly large:
What do I need to do to create an exe of my project?
Assuming I have the right idea for doing this, how do I include the external (DarkGDK) libraries in the linker input?
Is this all I need to do?


Thank you in advance.
vletters
16
Years of Service
User Offline
Joined: 4th Jan 2008
Location:
Posted: 4th Jan 2008 21:04
First of all, thank you for this explanation. Unfortunately I am still unsure but perhaps you can fill in the blanks for me?

I have written a program I would like to make into an executable file. Naively, I assumed this would be as simple as it is in Visual Basic (just hit "Publish").

My understanding, conceptually, is that I need to compile the code, then link it to the required libraries (in my case, the Dark GDK libraries and the C++ standard library). Once that is done, the project can be built into an executable file.

I have read the information here and what is available through MSDN but I'm still very unsure as to how to go about building my program. The project debugged smoothly until I tried to build it. I am now greeted with a "No Debugging Information" error when I try to debug.

I know I am going to have to change settings in the Project properties, particularly under Linker/Includes. I can do as you suggest and ignore all default libraries, then specify to depend on the standard C++ library under additional dependencies. However, I do not know how to specify to include libraries such as the DarkGDK library!

So my questions are:

Once I have completed the code, what do I need to do to create an executable file?

The MSDN information had bits about creating a file that would simply be clicked (i.e no installer). This would be optimal but I was quickly lost trying to determine how to follow that route.

I think I understand the concepts, at least in general, but I do not know how to apply those in the project properties. I hate to sound like a noob, but can you tell me how to set up the compiling and linking properly? I heartily suspect I am having the same problem many are experiencing (although I cannot even see an option to compile my project and so have not seen those tell-tale errors).

Thank you
Pharoseer
17
Years of Service
User Offline
Joined: 21st Feb 2007
Location: Right behind you
Posted: 7th Jan 2008 08:31 Edited at: 7th Jan 2008 08:36
Hey Tempicek,

I think I follow you, but I agree with Mongoose. I've NEVER had to fight this hard with the linker before. I'm feeling a little thickheaded today though. So I still want to double check and make sure I'm on the same page as you.

If I use one of the wizards so that my project settings are pre-defined for me and simply add the line:



...then I should EXPECT to get linker errors?

Just by adding that I get 3 linker errors and have to switch from the /MTd to the /MT option under the Code Generation settings to change my runtime libraries.

Is that what you're saying is normal with DGDK, or did I miss something? Sorry if I'm being dense. Sometimes you have to tell it to me like you were explaining it to a preschooler. A few too many kicks to the head I guess.

-Frank

[edit]
Quote: "Therefore the code you are working with is always using release version of runtime libraries. Since their libraries expect release version of standard libraries, you have to link against release version too. And since you have to link against one version only, you can not use debug version of runtime libraries."


Sorry, I reread your initial post and that quote sorta jumped out at me and answered my question. Thanks for the excellent explanation by the way!
[/edit]
tempicek
16
Years of Service
User Offline
Joined: 27th Nov 2007
Location: Prague
Posted: 7th Jan 2008 12:13
to vletters:

Quote: " I have tried "Build Solution" and "Build Project" but neither has yielded a result. In fact, I now find that I cannot debug! "No Debugging Information" greets me when I try to. "


What you probably did is that you changed the build configuration set. On the main toolbar, just beside the "Start Debugging" button, you can see a combobox with these options:
"Debug"
"Release"
"Configuration Manager..."
There you probably set the "Release" option, which is ok if you are trying to publish your game, but it's not ok if you are trying to debug. That's why you get your message "No debug info" when you hit F5.

"Build Solution" is really the way to go once you properly chose the configuration set (Release for publishing). You will see the result of the build process in Output Window. If the code compiles (and links) properly, you can see this message at the end:
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
This means that your game is ready, so you have the executable you were up to (just pick it up in the folder where it compiles to).

Quote: "I am guessing the linker should also link the header files for these libraries to my compiled code as well."


No, the linker doesn't use header files, those are used by compiler to understand your code. Linker uses only libraries as input, where those symbols are already compiled. But that doesn't matter now, just keep focusing on the problem...

Quote: "Ok, so I can define all these things by clicking on properties for my project. From what I understand, the main things that will need to be changed are under the Linker/Input section."


Exactly.

Quote: "If I choose to ignore all default libraries, I can easily choose to include the Standard Library (the only one of the default libraries I think I am using). However, I do not know how I should properly go about including the DarkGDK libraries."


Well, doing this with GDK is a bit more tricky. So I rather recommend here to stay with the easier way to let all libraries be added automatically and ignore some specific (libcmtd.lib most likely in your case; and NOT using "Ignore all default"). I'm sorry for spreading confusion - I wanted to give everyone the useful background, but doing it the hardest way is better when you feel like home on this field. When you use their wizard to create a project, it doesn't contain the needed libraries on linker input (I don't really understand why they do this so complicated, but it's their choice...), so you would have to add every single library manually (there are about 30 of them) and you better stay away from that since you likely end with some other problems. For non-GDK projects, or once GDK devs add this setting to their wizard so you don't have to do that manually, this would be a better solution. But for now, rather stay with "ignoring some" than "including specific".

That should also answer your other questions so I hope you can manage that now.
tempicek
16
Years of Service
User Offline
Joined: 27th Nov 2007
Location: Prague
Posted: 7th Jan 2008 12:18
To Pharoseer:

Quote: "If I use one of the wizards so that my project settings are pre-defined for me and simply add the line:

#include <string>

...then I should EXPECT to get linker errors?

Just by adding that I get 3 linker errors and have to switch from the /MTd to the /MT option under the Code Generation settings to change my runtime libraries."


Exactly (as you already figured out). I'm sorry if I made it too complicated while you often need to do just a minor change(s). I was trying to explain the background so you know WHY you are doing that (and can possibly fix different situations also).
Pharoseer
17
Years of Service
User Offline
Joined: 21st Feb 2007
Location: Right behind you
Posted: 7th Jan 2008 22:24
Hey Tempicek,

No need to apologize. I was being slow-witted yesterday. I had it fixed in my head that what I was doing was a hack and wasn't letting myself understand your explanation. You did a GREAT job explaining why I had to do that.

Now I need to roll up my sleeves and actually learn some of that stuff you were trying to teach.

Thanks again!

-Frank
tempicek
16
Years of Service
User Offline
Joined: 27th Nov 2007
Location: Prague
Posted: 8th Jan 2008 11:11 Edited at: 8th Jan 2008 11:12
to vletters & others:

It probably created a bit of confusion with my side note:

Quote: "As for myself, I enjoy the way of precise configuration, so I set the "/NODEFAULTLIB" and then set the input accordingly to my setting."


To clarify this method, I will follow up on this to show how you can manage this with GDK. Because, again, there's a betrayal in the GDK project wizard.

What we want to do is this: set up the project (linker configuration in particular) so that you explicitly tell which libraries you want as a linker input, rather than telling which default libraries to omit. The motivation for this is simple - it's generally clearer as you see exactly the linker input (but it needs some knowledge).

Setting this up in a common project isn't that hard. It's a bit more complicated with GDK, though, mainly for two reasons:

1) They decided to distribute GDK as a set of about 30 libraries (in contrast to providing one single library), which you wouldn't like to enumerate for every single project built on GDK.
2) Their wizard doesn't set this up for some reason. Rather than that, those libraries are added to the list of default libraries in the source code (see DarkSDK.h). So, even if those libraries are not listed in project's linker input, they are actually linked in.

So, if you set the linker with '/NODEFAULTLIB' switch ("Ignore All Default Libraries" option), you get tons of unresolved externals, since those libraries are considered 'default' and thus omitted. Technically speaking, the only thing you need to do is enumerating all the default libraries in the "Proj.sets. | Linker | Input | Additional Dependencies" setting. The only downside of this is, that there are dozens of them. Anyway, I will make this easier for you and here is the list:

1) C/C++ runtime libraries - as mentioned in my initial post
2) GDK libraries
3) Used system libraries
4) DirectX libraries

The complete list is here:
libcmt.lib libcpmt.lib oldnames.lib darksdk.lib core.lib text.lib display.lib input.lib file.lib basic2D.lib bitmap.lib sound.lib music.lib sprites.lib image.lib animation.lib light.lib camera.lib basic3D.lib matrix.lib world.lib particles.lib 3dmaths.lib ftp.lib memblocks.lib shaderdata.lib multiplayer.lib system.lib convx.lib conv3ds.lib convmd2.lib convmd3.lib convmdl.lib terrain.lib shell32.lib wininet.lib Msacm32.lib winmm.lib d3dx9d.lib d3d9.lib dplayx.lib dxguid.lib dinput8.lib d3dxof.lib dsound.lib

Note that you may need different standard libraries depending on your runtime setting (here libcmt.lib and libcpmt.lib) and that you also need oldnames.lib (already listed above) because GDK uses deprecated names for some standard functions. With this line you should be able to link successfully without need to define specific libraries to be ignored.

//rem
FERSIS
17
Years of Service
User Offline
Joined: 17th May 2006
Location:
Posted: 8th Jan 2008 19:58
tempicek great read
thanks for taking the time to write it down
cheers
vletters
16
Years of Service
User Offline
Joined: 4th Jan 2008
Location:
Posted: 10th Jan 2008 02:41
This is great. Thanks!

Login to post a reply

Server time is: 2024-05-03 23:54:09
Your offset time is: 2024-05-03 23:54:09