Lnk4098: defaultlib "×××" conflicts with use of other libs

Source: Internet
Author: User
the compilation tool of vcpus is cl.exe, it has several options related to the standard Program Library: /ml,/MLD,/mt,/MTD,/MD,/MDD. These options tell the compiler application the version of the C standard library to be used. /Ml (default option) corresponds to the standard library (libc) of the single-thread static version. lib);/MT corresponds to the standard library (libcmt. lib). At this time, the compiler will automatically define the _ Mt macro;/MD corresponding to the multi-threaded dll version (imported into msvcrt. lib, DLL is msvcrt. the compiler automatically defines two macros: _ MT and _ DLL. The option D will allow the compiler to automatically define one more _ debug macro, indicating that the debugging version of the corresponding standard library is used. Therefore,/MLD corresponds to the single-thread static standard library (libcd. lib),/MTD corresponds to the multi-threaded static standard library (libcmtd. lib),/MDD corresponds to the debugging version of the multi-threaded DLL standard library (imported to msvcrtd. lib, DLL is msvcrtd. DLL ). Although we did clearly tell the compiler application what version of the standard library we want to use during compilation, when the compiler is finished, how does the linker know who the target files are missing when it's time to start? In order to pass on lovesickness, our compiler has done something secret. There will be a special area in the target file compiled by Cl (if you are concerned about the location of the area in the file, refer to coff and PE file formats) stores information that instructs the linker on how to work. One of them is called the default library, which specifies several library file names, when the linker scans the target file, the names of these databases will be processed in the order they appear in the target module: if the library does not exist in the current input file list, add it to the end of the input file list, otherwise it will be skipped. Here, we will first make a small experiment. Write a simple program and save it as main. C:

/* Main. C */
Int main () {return 0 ;}

Use the following command to compile main. C (what? You never use command lines to compile programs? This ......):

CL/C main. c

/C tells Cl to compile only source files without links. Because/ml is the default option, the preceding command is equivalent to Cl/C/ml main. C. If there is no problem (it's the best thing to do if something goes wrong! Of course, unless your environment variables are not set, you should find the vcvars32.bat file in the bin directory of VC and run it .), A main. OBJ file will appear in the current directory, which is our lovely target file. Open it with a text editor (yes, the text editor, do not be afraid) and search for the "defaultlib" string. You will usually see something like this: "-defaultlib: libc-defaultlib: oldnames ". Aha, that's right.
Is the default library information stored in the target file. Our target file clearly specifies two default libraries. One is the standard library libc of the single-threaded static version. lib (this is consistent with the/ml option); one is oldnames. lib (it is designed to be compatible with Microsoft's previous C/C ++ development systems. It is basically not needed, and can be ignored for simplified discussion ). In addition, if you use

/* XXXX indicates the actual library file name */
# Pragma comment (Lib, "XXXX ")

The compile directive command (compiler ctictive) specifies the library to be linked. This information will also be saved to the default library information item of the target file, which is located before the default standard library. If there are multiple such commands, the order in which the corresponding library names appear in the target file is exactly the same as that in the source program (and before the default standard library ).

The chain connector of vcss is link.exe. Because main. OBJ stores the default library information, you can use

Link main. OBJ libc. Lib

Or

Link main. OBJ

To generate the executable file main.exe. These two commands are equivalent. But if you use

Link main. OBJ libcd. Lib

The linker will give a warning: "Warning lnk4098: defaultlib" libc "conflicts with use of other libs; Use/nodefaultlib: Library ", because the default values of the standard library version you explicitly specify are different from those of the target file. Generally, ensure that the default standard library versions specified for all target files merged by the linker are consistent. Otherwise, the compiler will give the above warning, the lnk2005 and lnk1169 Link errors sometimes occur and sometimes do not. So when is this sometimes? Well, don't worry. Everything Below is exactly what you want to get to the bottom.

Create a source file named mylib. C. The content is as follows:

/* Mylib. C */
# Include <stdio. h>

Void Foo (void)
{
Printf ("% s", "I am from mylib! /N ");
}

Use

CL/C/MLD mylib. c

Command compilation. Note that the/MLD option specifies libcd. Lib as the default standard library. Lib.exe is a VC command used to package the target file into a library, so we can use

LIB/out: My. Lib mylib. OBJ

Package mylib. OBJ into a library. The output file name is my. Lib. Next, change main. C:

/* Main. C */
Void Foo (void );

Int main ()
{
Foo ();
Return 0;
}

Use

CL/C main. c

Compile and then use

Link main. OBJ my. Lib

. This command can successfully generate main.exe without generating lnk2005 and lnk1169 Link errors. You only get a warning message: "Warning lnk4098: defaultlib" libcd "conflicts with use of other libs; Use/nodefaultlib: Library ". Based on the scan rules described above, we can analyze what the linker has done at this time (add a/verbose option to see the detailed link process, but note that, almost all c compilers add an underline before the symbol and then output it, therefore, the symbolic names displayed in the output information of the target file and link are one more '_' than those seen in the source program, which cannot be ignored .).

at the beginning, E, U, and D are empty sets. The linker first scans main. OBJ, set its default standard library libc. lib is added to the end of the input file list. It is added to the E set, while UN-Resolved foo is added to U, and main is added to D. Then scan my. lib, because this is a library, it will take all the symbols in the current U (of course, a foo now) and my. all target modules in lib (of course there is only one mylib. OBJ. Result: mylib. OBJ does define Foo, so it is added to E, foo is transferred from u to D, un-parsed printf is added to U, the specified default standard library libcd. lib is also added to the end of the input file list (in libc. after Lib ). Constantly iterate on the modules of my. Lib library to match the symbols in U until u and d do not change. Obviously, now we have reached such a fixed point, so we will scan the next input file, which is libc. Lib. The linker found libc. printf. in OBJ, printf is defined, so printf is moved from u to D, printf. OBJ is added to E, all the symbols defined by OBJ are added to D, and unparsed symbols in OBJ are added to u. If the/entry option is not specified during the link, the default entry point of the linker is the maincrtstartup function (the default entry point of the GUI program is winmaincrtstartup ), it is defined in crt0.obj, so crt0.obj and its directly or indirectly referenced modules (such as malloc. OBJ, free. objects) are added to E, and the default libraries specified by these target modules (crt0init only. OBJ specifies kernel32.lib) to be added to the end of the input file list, and U and D are updated at the same time. Constantly match libc. each module in lib reaches the fixed point, and then processes libcd. lib, but none of the target modules in it define a symbol in U, so the linker skips it to enter the last input file kernel32.lib. In fact, the existing and unresolved symbols in u can be found in the definition. When kernel32.lib is processed, the u must be empty, the linker merges all modules in e to generate executable files.

The above describes an example of a successful link even though different versions of the default standard library are specified for each target module. Next, you will see a miserable failure caused by this rigor.

Modify mylib. C as follows:

# Include <crtdbg. h>

Void Foo (void)
{
 // Just a test, don't care about Memory Leak
_ Malloc_dbg (1, _ normal_block, _ file __, _ line __);
}

Among them, _ malloc_dbg is not an ansi c standard library function. It is a debugging version of malloc provided by the VC standard library. It works with related functions to help developers catch various memory errors. To use it, you must define the _ debug macro. Otherwise, the pre-processor will convert it to malloc automatically. Continue to use

CL/C/MLD mylib. c
LIB/out: My. Lib mylib. OBJ

Compile and package. When you use

Link main. OBJ my. Lib

What do we see during the link? My God, a bunch of lnk2005 plus an lnk1169 expensive for "Fatal error", of course, the lnk4098 is also indispensable. Is the linker crazy? No, you have wronged the poor linker. I promise it will keep working with my due diligence.

E, U, and D are empty at the beginning, and the linker scans main. OBJ, set libc. add lib to the end of the input file list and set main. add OBJ to E, add Foo to U, and add main to D. Then scan my. Lib, so mylib. obj is added to E, libcd. Lib is added to the end of the input file list, foo is transferred from u to D, and _ malloc_dbg is added to u. Then scan libc. lib. no target module in lib defines _ malloc_dbg (It only exists in the standard library of the debugging version). Therefore, no module is added to E because of _ malloc_dbg. But because libc. crt0.obj in lib defines the default entry point function maincrtstartup, so crt0.obj and its directly or indirectly referenced modules (such as malloc. OBJ, free. objects) are added to E, and the default libraries specified by these target modules (crt0init only. OBJ specifies kernel32.lib) to be added to the end of the input file list, and U and D are updated at the same time. Constantly match libc. each module in lib processes libcd until it reaches the fixed point. lib, dbgheap is found. OBJ defines _ malloc_dbg, so dbgheap. OBJ is added to E, its unparsed symbols are added to U, and all other symbols defined by OBJ are added to D. Then, the disaster will come. Previously, symbols such as malloc were already in D (with libc. malloc in Lib. OBJ is added to E), while dbgheap. OBJ and other modules introduced by it define many cognominal symbols including malloc, leading to redefinition conflicts. Therefore, after the linker finishes processing all input files (yes, even if there is a redefinition conflict in the middle, it will process all files to generate a complete conflict list), it will have to report: this cannot be done.

Now we should know that the linker has no responsibility at all, and the responsibility lies with ourselves. We carelessly linked the target file (main. OBJ) that is inconsistent with the default standard library version to the Library (My. Lib), causing a catastrophic disaster. The solution is simple. You can use the/MLD option to recompile main. c; or re-compile mylib with the/ml option. c; or simply ignore the default library xxx with the/nodefalib Lib: XXX option when linking, but this method is very insecure (think about why ?), Therefore, it is not recommended.

In the above example, we haveSource code(Mylib. C), so you can recompile these sources with different optionsCodeAnd package again. However, if a third-party library is used and the source code is not provided, we only need to change the compilation options of our program to adapt to these libraries. But how do I know the default library specified by the target module in the library? In fact, a small tool of vcpus can be used to complete the task. This is dumpbin.exe. Run the following command

Dumpbin/directives my. Lib

Find the "linker ctictives" Bootstrap information in the output. You will surely find that each such information contains several strings similar to "-defaultlib: XXXX, XXXX indicates the default library name specified by the target module. (Note that if the/ZL option is specified during compilation, no defalib lib information is available in the target module ).

Knowing the default standard library specified by a third-party library and compiling our application with appropriate options can avoid lnk2005 and lnk1169 Link errors. If you like IDE, you can go to "Project Properties"-> "C/C ++"-> "code generation) "->" Run-Time library "sets the default standard library version of the application, which is the same as the command line option.

 

 

 

You are trying to link with incompatible libraries. important the run-time libraries now contain ctictives to prevent mixing different types. you'll receive this warning if you try to use different types or debug and non-DEBUG Versions of the run-time library in the same program. for example, if you compiled one file to use one kind of run-time library and another file to use another kind (for example, single-threaded versus multithreaded) and tried to link them, you'll get this warning. you shoshould compile all source files to use the same run-time library.

 

In a word, there is a conflict between Lib. Some libs to be imported must be deleted.

 

 

 

Version Type Library Used Ignored Library
R release Single thread Libc. Lib Libcmt. Lib, msvcrt. Lib, libcd. Lib, libcmtd. Lib, msvcrtd. Lib
Multithreading Libcmt. Lib Libc. Lib, msvcrt. Lib, libcd. Lib, libcmtd. Lib, msvcrtd. Lib
Multithreading with DLL Msvcrt. Lib Libc. Lib, libcmt. Lib, libcd. Lib, libcmtd. Lib, msvcrtd. Lib
D debug Single thread Libcd. Lib Libc. Lib, libcmt. Lib, msvcrt. Lib, libcmtd. Lib, msvcrtd. Lib
Multithreading Libcmtd. Lib Libc. Lib, libcmt. Lib, msvcrt. Lib, libcmtd. Lib, msvcrtd. Lib
Multithreading with DLL Msvcrtd. Lib Libc. Lib, libcmt. Lib, msvcrt. Lib, libcd. Lib, libcmtd. Lib

 

For example, to compile a single-threaded project of the release version, add the following parameters to the linker command line:

 

/Nodefaultlib: libcmt. lib/nodefaultlib: msvcrt. lib/nodefaultlib: libcd. lib/nodefaultlib: libcmtd. lib/nodefaultlib: msvcrtd. Lib

 

Of course, it can also be configured through the development environment of vc6.0. Select project-> setting. In the displayed project Setting dialog box, click the link tag, select input from the category drop-down menu, and click Ignore libraries below: in the input box, enter the corresponding libs in the ignored library box. Pay attention to the current build version when you enter it. libs are separated by commas. "Ingore all default libraries" cannot be checked.

 

 

 

 

 

Specify the Runtime Library connected to your project
/MT multi-thread application
/MTD multi-thread application (Debug)
/MD multi-thread DLL
/MDD multi-thread DLL (Debug)

 

 

 

 

 

 

 

Some time ago, when compiling a program that references a self-written static library, there were always multiple redefinition errors during the link, and your code clearly did not redefine these things, for example:
Libcmt. Lib (_ file. OBJ): Error lnk2005: ___ initstdio already defined in libc. Lib (_ file. OBJ)
Libcmt. Lib (_ file. OBJ): Error lnk2005: ___ endstdio already defined in libc. Lib (_ file. OBJ)
Libcmt. Lib (_ file. OBJ): Error lnk2005: _ cflush already defined in libc. Lib (_ file. OBJ)
Libcmt. Lib (_ file. OBJ): Error lnk2005: _ iob already defined in libc. Lib (_ file. OBJ)
Libcmt. Lib (osfinfo. OBJ): Error lnk2005: _ alloc_osfhnd already defined in libc. Lib (osfinfo. OBJ)
Libcmt. Lib (osfinfo. OBJ): Error lnk2005: _ set_osfhnd already defined in libc. Lib (osfinfo. OBJ)
Libcmt. Lib (osfinfo. OBJ): Error lnk2005: _ free_osfhnd already defined in libc. Lib (osfinfo. OBJ)
Libcmt. Lib (osfinfo. OBJ): Error lnk2005: _ get_osfhandle already defined in libc. Lib (osfinfo. OBJ)
Libcmt. Lib (osfinfo. OBJ): Error lnk2005: _ open_osfhandle already defined in libc. Lib (osfinfo. OBJ)
Libcmt. Lib (tolower. OBJ): Error lnk2005: _ tolower already defined in libc. Lib (tolower. OBJ)
Libcmt. Lib (tolower. OBJ): Error lnk2005: _ tolower already defined in libc. Lib (tolower. OBJ)
And so on.

 

The preliminary estimation is about the compiler. By searching and viewing msdn on the internet, it turns out to be about the Single-thread or multi-thread runtime routines of Visual C ++ compiler options: my static library is in/ml single-threaded version during compilation, and the program that references it is in/MT multi-threaded version. They are respectively talking about libc during compilation. lib and libcmt. when Lib is connected to the Code, it is estimated that libc. lib and libcmt. lib is only the difference between a single thread and multiple threads, and the basic code is almost the same, so it will produce a re-definition error when the link is generated; then it will be okay to change the option/ml for compiling the static library to/mt.

 

Note:/MD is also a multi-threaded version. The user linked library to be applied must have the same compilation options as the application./MD and/MT may sometimes have errors, sometimes I did not. I tried this situation, but/MD and/ml seem to be okay./MT and/ml certainly have problems. It is unclear if there are other situations. If you are interested, please test it. ^ _ ^

 

If the code is used for multithreading, it is best to compile it into a multi-threaded version, otherwise unexpected problems may occur.

 

Compiler option settings (vc6): Project-> Settings-> C/C ++-> project options can be modified

 

Appendix:

 

The following describes the Visual C ++ compiler options in msdn:

 

These options select a single-threaded or multi-threaded runtime routine to indicate whether the multi-threaded module is a DLL, and select the release or debug version of The Runtime Library.

 

Option description
/MD defines _ MT and _ DLL to select the specific multi-thread version and dll version of the runtime routine from the standard. h file at the same time. This option also enables the compiler to put the library name msvcrt. Lib into the. OBJ file.
The application compiled with this option is statically linked to msvcrt. Lib. This library provides a code layer that allows the linker to parse external references. The actual working code is included in msvcr71.dll. This library must be available for applications linked to msvcrt. Lib at runtime.

 

When _ static_cpplib (/d_static_cpplib) is defined and/MD is used, it causes the application to pass through the static multi-threaded Standard C ++ Library (libcpmt. lib) instead of the dynamic version (msvcprt. lib), and still use msvcrt. lib is dynamically linked to the master CRT.

/MDD defines _ debug, _ Mt, and _ DLL to select the debugging multi-thread and DLL-specific versions of the runtime routine from the standard. h file. It also enables the compiler to put the library name msvcrtd. Lib into the. OBJ file.
/Ml causes the compiler to put the library name libc. Lib into the. OBJ file so that the linker can use libc. lib to parse external symbols. This is the default operation of the compiler. Libc. Lib does not support multithreading.

 

/MLD defines _ debug and causes the compiler to put the library name libcd. Lib into the. OBJ file so that the linker can use libcd. lib to parse external symbols. Libcd. Lib does not support multithreading.

 

/MT defines _ mt to select a specific multi-thread version of the runtime routine from the Standard Header (. h) file. This option also enables the compiler to put the library name libcmt. Lib into the. OBJ file so that the linker can use libcmt. lib to parse external symbols. To create a multi-threaded program,/Mt or/MD (or their debugging equivalent options/MTD or/MDD) is required ).

 

/MTD defines _ debug and _ Mt. Defining _ mt will result in selecting a specific multi-thread version of the runtime routine from the standard. h file. This option also enables the compiler to put the library name libcmtd. Lib into the. OBJ file so that the linker can use libcmtd. lib to parse external symbols. To create a multi-threaded program,/MTD or/MDD (or their non-debugging equivalent options/Mt or Md) is required ).

 

/LD create DLL.
Pass the/DLL option to the linker. The linker searches for the dllmain function, but does not need this function. If the dllmain function is not compiled, the linker inserts the dllmain function that returns true.

 

/LDD create and debug the DLL. Define _ debug.

 

Warning:

 

Do not mix the static and dynamic versions of the Runtime Library. There are multiple runtime database copies in a process, which may cause problems because the static data in the copies is not shared with other copies. The linker prohibits the use of both static and dynamic version links in the. exe file, but you can still use two (or more) Copies of the Runtime Library. For example, if it is linked to the Runtime library using the dynamic (DLL) version. when the EXE file is used together, the dynamic link library linked by the Runtime Library of the static (non-DLL) version may cause problems. (You should also avoid mixing the debug and non-DEBUG Versions of these libraries in a process ).


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.