When I am using a non-standard library in C++ I have to add the library name in linker-->input-->additional dependencies . But the alternative is to write
#pragma comment(lib , "library name")
Are these two methods completely the same?
They are not.
The said pragma adds a defaultlib. The option a mandatory lib to the linker line.
The latter is processed no matter what, and you get error if it is missing.
The default lib is ignored silently if not found. And using options "ignore default libs" or "ignore specific default lib" can be used to dismiss its use even if it is present.
These are two ways of doing the same thing. i.e. the compiler telling the linker which libs to look for. #pragma comment has other functions too like adding data like compiler info or any other meta data to the object file.
#pragma comment is VC++ specific.
Related
Situation:
Static library LIB1, compiled from source and linked as lib1.lib (with /MD).
Uses library LIB2 and has inside objects from lib2.lib
Static library LIB2, also compiled with /MD.
EXE that (not directly) depends on both libraries.
Result of linking this EXE on MSVC 15.9.19: a lot of LNK2005 errors like
lib2.lib: error LNK2005: "function <funcsig> already defined in lib1.lib"
Also I get a lot of warnings like
lib1.lib: warning LNK4099: PDB 'lib2.pdb' was not found with 'lib1.lib' or at '<path>'; linking object as if no debug info
The question: why didn't the linker merge duplicate definitions? How do I diagnose the exact reason for this problem?
Thanks!
UPDATE:
The errors are NOT about the standard library. They are about the Google Protobuf functions. LIB2 is Google's libprotobuf.lib. LIB1 is also Google's OR-Tools library that uses Protobuf. But we also use Protobuf, hence the conflict!
This link to MSDN will almost certainly help.
As you say these are not standard C/C++ functions, you can ignore the sections about the mixing Debug and Release code. Unfortunately this still leaves you with plenty of possible causes. This one is a good one to rule out.
This error can occur if you mix use of static and dynamic libraries when you use the /clr option.
If you view the command line options as you compile, either by switching on verbose mode or examining the properties of each file.
Once this is ruled out, all the other causes are that you literally declaring the same thing (function/variable) twice. The most likely way for this to happen is to put something (like a function) in a header file, which is included by more than one module file. Diagnosing this without seeing the code is hard. You must pick one of the errors, and select part of the name that is not mangled, basically the human readable bit. You then need to examine where it is declared, and see if is in a header. If it is not, you must be including a non-header from a source file. A quick (and dirty) way to find where a file is included from is to add a #pragma message to the file, then recompile one file at a time to see when it is printed. To understand why it is included use show includes.
If the symbol is declared from a header file, you must fix it, by making it a forward declare.
If you don't know how to do this, I would suggest starting a new question, along the lines of, "how do I forward declare this?". It should get you answers pretty quickly.
Hope this helps.
I am trying to include the UIAutomation.h library in my Code::Blocks client but I think I am doing something wrong. I just typed:
#include <UIAutomation.h>
at top of my program where all my other headers are and I get this error message right away when I compile:
fatal error: UIAutomation.h: No such file or directory
I am a bit of a newb with these things, and I saw some people talk online about a "linker". If a linker has anything to do with me being able to use the UI Automation library, please let me know what is a linker and how do I use it? Otherwise, please let me know what you think I could be doing wrong.
ohh ok so I can do like #include "c:\programfiles\...\UIAutomation.h"??.. do I have to include the <>? like: #include <"c:\blah\blah"> or #include "c:\blah\blah"??
Yes you can do that, but that's very probably a bad idea!
You should better use the -I option of the actual compiler to specify where to search for additional (besides standard) include files:
-I"c:\programfiles\UIAutomation\include"
Also you'll need to set the -L option for the linker to specify where to find the corresponding libraries for UIAutomation:
-L"c:\programfiles\UIAutomation\lib"
and the library itself with the -l<lib> option:
-lUIAutomation
The latter name depends which library files are actually present in the directory specifed with the -L option. The above sample expects to find a file named libUIAutomation.a or libUIAutomation.lib there.
I'm not really experienced with the codeblocks IDE, but from what I remember it allows you to set these options in the project settings.
NOTE:
All the specific option references given above, refer to the actual toolchain used for your codeblocks project. These will apply for the most commonly used toolchains (e.g. like GCC), but may vary for different ones. Though, there- will be certainly equivalent options for the compiler and linker tool used.
I'm using boost for a project I'm working on. Some of my files include one or more of the boost headers which in turn include other boost headers, which in one of them there is a variable which is set but not used. This prints an ugly warning to my screen which makes it hard to read the output especially when I have a real compilation error but I need to look carefully in the output to distinguish which text belongs to the set but not used warning and which is related to the real compilation error I want to solve.
I don't want to disable this warning to the entire project or even to some specific files in my project because I want to see this warning if I set a variable in my code but I don't use it. I want only the warning which happens in a specific line and specific file to be ignored.
Is there an option for gcc to suppress specific warnings in specific location in the code?
gcc offers diagnostic pragmas. See http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html.
Use these in your code before and after you #include those third party headers. Do not modify those the third party code to suit your compilation flags.
What does #pragma comment mean in the following?
#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")
#pragma comment is a compiler directive which indicates Visual C++ to leave a comment in the generated object file. The comment can then be read by the linker when it processes object files.
#pragma comment(lib, libname) tells the linker to add the 'libname' library to the list of library dependencies, as if you had added it in the project properties at Linker->Input->Additional dependencies
See #pragma comment on microsoft.com
I've always called them "compiler directives." They direct the compiler to do things, branching, including libs like shown above, disabling specific errors etc., during the compilation phase.
Compiler companies usually create their own extensions to facilitate their features. For example, (I believe) Microsoft started the "#pragma once" deal and it was only in MS products, now I'm not so sure.
Pragma Directives It includes "#pragma comment" in the table you'll see.
HTH
I suspect GCC, for example, has their own set of #pragma's.
The answers and the documentation provided by MSDN is the best, but I would like to add one typical case that I use a lot which requires the use of #pragma comment to send a command to the linker at link time for example
#pragma comment(linker,"/ENTRY:Entry")
tell the linker to change the entry point form WinMain() to Entry() after that the CRTStartup going to transfer controll to Entry()
These link in the libraries selected in MSVC++.
Pragma directives specify operating system or machine specific (x86 or x64 etc) compiler options. There are several options available. Details can be found in https://msdn.microsoft.com/en-us/library/d9x1s805.aspx
#pragma comment( comment-type [,"commentstring"] ) has this format.
Refer https://msdn.microsoft.com/en-us/library/7f0aews7.aspx for details about different comment-type.
#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")
The above lines of code includes the library names (or path) that need to be searched by the linker. These details are included as part of the library-search record in the object
file.
So, in this case kernel.lib and user32.lib are searched by the linker and included in the final executable.
From this thread
http://www.codeguru.com/forum/showthread.php?p=1863547
It seems this cannot be done with:
#pragma comment(linker, "/out:mycool.exe")
Is there some simple way this can be done without having to use project settings, make files etc?
Added:
Why do I want to do this.
Well this gets into another subject which is probably my next question - working with the IDE.
I have to provide many examples in one project. They are simple single files that demonstrate different ways of doing things and each one should really be a different executable EXample1.exe, Example2.exe.
I only want to paste the source code or hand someone a SINGLE file with everything needed to make the example executable (on a web forum for example. I do not want to attach a 3.6MB project folder just to get a different executable name!
Compiling transcends source code. Source code only exists, and something has to take it and make something of it. Anything you do in source code is really just going to be a directive to the compiler. You might as well use project settings. This stuff isn't standard, because the standard only covers behavior and definitions of source code, not compilers.
g++ takes the output file as a parameter: g++ -o myexe.exe main.cpp. What should it do if it comes across a "output should be this!" directive in the source code?
Same with cl (Visual Studio), it passes the output setting into the command line.
Not to say it's impossible, but I doubt it's worth it to try and come up with a way to do it, let alone make it standard.
To use the linker pragma comment, the output file must NOT be specified in the linker section of the project properties:
project -> properties -> Linker -> General -> Output File
Delete the entry: $(OutDir)\$(ProjectName).exe
then the prama statement will work:
pragma comment(linker, "/out:mycool.exe")
Thanks to JC for the walkthrough
Specifying a complete path is not possible
http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/11a06ecd-dcca-4d81-8626-ba0c5a1835c1/
but the work around is:
What I do is have a header file loacated somewhere near the library file, this header will include the pragma line.
pragma comment(lib, FILE "../libs/mylibary.lib")
if FILE is "C:\Project\SharedLibs\Xvid\latest.h"
then the pragma will include
"C:\Project\SharedLibs\Xvid\libs/mylibary.lib" once it has normalized the uri to remove the ..'s
this will always cause the pragma to include the library with an absolute path created from the path of the accompanying header.
I use this system to include a single header in a project and regardless of the relative paths between the lib and project the lib will always be included cleanly.
Added:
The full path can be specified as long as it is 8.3 format. This can present problems for a path like:
C:\Program Files\Abyss Web Server\htdocs\
Program files is commonly Progra~1
but a folder name with a space is more tricky. In this case it becomes AbyssW~1
The \ must be escaped resulting in \ producing a working pragma of:
#pragma comment(linker, "/out:C:\\Progra~1\\AbyssW~1\\htdocs\\MyApp.exe")
as kibibu showed:
#pragma comment(linker, "/out:\"C:\\Program Files\\Abyss Web Server\\htdocs\\MyApp.exe\"")
also works
If you don't want to stray too far from a stock Visual C++ installation, you should consider using NMake. It can integrate with the IDE using project files, but it can also simply be run from the command-line very easily. It's also far more lightweight than project files for generating an arbitrary number of simple and similar executables.