pragma comment(lib) not working - c++

Given this library:
lib1.h:
#pragma once
#include <windows.h>
void foo();
lib1.cpp
#include "lib1.h"
void foo() {
MessageBox(NULL, "XXX", "YYY1", MB_OK);
}
Created in the command line with the next commands:
cl /c lib1.cpp
lib lib1.obj
And then this little test:
#pragma comment(lib, "lib1")
#include "lib1.h"
void start() {
foo();
}
I've tried to run it on a windows vs2015 project setting:
/NODEFAULTLIB
entry:start
optimization disabled (/Od)
(security check disabled) /GS-
But I'm facing a linker error such as:
main.obj : error LNK2019: unresolved external symbol "void __cdecl foo(void)" (?foo##YAXXZ) referenced in function "void __cdecl start(void)" (?start##YAXXZ)
I've tried changing the pragma comment to #pragma comment(lib, "lib1.lib"), #pragma comment(lib, ".\\lib1.lib"), #pragma comment(lib, "./lib1.lib") and none of them worked.
I've also tried to include in the linker additional paths the path of lib1.lib and then using either #pragma comment(lib, "lib1.lib") or ``#pragma comment(lib, "lib1.lib")`, no luck.
In fact, the funny thing is, when turning on the /VERBOSE in the linker I don't see any linker's attempt to use the #pragma directive. Of course, If i added lib1.cpp or lib1.lib to the project it'd work but I'm trying to figure out how to use the pragma directive... So, anyone could explain what's going on here and how to solve this issue?

Don't use /NODEFAULTLIB, it basically instructs the linker to ignore the lib #pragma. Explanation from here for instance:
When you use #pragma comment(linker) or #pragma comment(lib) you get a
special entry in the object file (it's a special COFF section usually
named ".drectve" with the directive bit set). Once the linker sees
this entry it treats it as if the switch was given on the linker
command line.
So:
t.cpp:
#pragma comment(lib,"advapi32.lib")
...
cl t.cpp
is equivalent to
t.cpp:
...
cl t.cpp /link /DEFAULTLIB:advapi32.lib
and when you add /NODEFAULTLIB to that last comment it will ignore whatever is specified as /DEFAULTLIB

Related

Cannot specify additional link file for clang

I've successfully compiled my main.cpp with clang, specifying additional include path via the command line options as follows: clang++ -I ./Dependencies/GLFW/include/ -S .\main.cpp.
However, when I try to link it by specifying the additional link library by the following command: clang++ -L ./Dependencies/GLFW/lib/glfw3.lib .\main.s it gives me a linker error main-8b7c4e.o : error LNK2019: unresolved external symbol glfwInit referenced in function main.
Any suggestions on what might be wrong? I'm sure that the relative path specified is correct, since the compile command gave me no issues.
main.cpp
#include <iostream>
#include <GLFW/glfw3.h>
int main() {
glfwInit();
std::cout << "Hello world" << std::endl;
return 0;
}
-L is for specifying folders to search for libraries in. The compiler ignores directories that don't exist.
Your command line should be:
clang++ ./Dependencies/GLFW/lib/glfw3.lib .\main.s
Please find below link for more detail about glfw header inclusion.
https://www.glfw.org/docs/latest/build_guide.html

Compiler Linker External Symbol Mhook_SetHook

Visual Studio 2017 (fresh install- command line version) gives error:
LNK2019: unresolved external symbol Mhook_SetHook referenced in function wmain
LNK2019: unresolved external symbol Mhook_UnHook referenced in function wmain
Compile command: cl /Y- /EHsc /DUNICODE mhook-test.cpp gdi32.lib user32.lib
I thought this might be related to C / C++ mixup, so I modified mhook.h as follows:
#ifdef __cplusplus
extern "C" {
#endif
BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction);
BOOL Mhook_Unhook(PVOID *ppHookedFunction);
#ifdef __cplusplus
} // extern "C"
#endif
This did not make a difference in results.
I don't understand why the linker is having a problem.
mhook-test.cpp came with the mhook library.
The mhook library is not distributed precompiled; it must be compiled into libraries which can then be specified to linker.
So, for each ".c" and ".cpp" file in the source code of the mhook directory:
"First, run cl /c /EHsc MathFuncsLib.cpp to compile the code and create an object file that's named MathFuncsLib.obj. (The cl command invokes the compiler, Cl.exe, and the /c option specifies compile without linking). Second, run lib MathFuncsLib.obj to link the code and create the static library MathFuncsLib.lib." - https://msdn.microsoft.com/en-us/library/ms235627.aspx
These must then be specified for the final compile command: "cl /Y- /EHsc /DUNICODE /D_UNICODE mhook-test.cpp gdi32.lib user32.lib mhook.lib disasm.lib misc.lib disasm_x86.lib cpu.lib"

Missing CoTaskMemFree when building LLVM example on Windows

I'm attempting to essentially follow the llvm Kaleidoscope example.
I'm on Windows. I built llvm from source per the directions on the site. It took quite a long time but it finally built successfully (no errors at least).
Then with my own code I am running this command:
$ clang-cl main.obj llvm/lib/LLVMCore.lib llvm/lib/LLVMSupport.lib /MDd -o build\test.exe
My main.cpp code has this in it:
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
std::unique_ptr<Module> module = llvm::make_unique<Module>("my cool jit", getGlobalContext());
And I'm not getting any parser errors but I am getting an error from the linker that for the life of me I cannot figure out:
LLVMSupport.lib(Path.obj) : error LNK2019: unresolved external symbol
__imp_CoTaskMemFree referenced in function "bool __cdecl
llvm::sys::path::getKnownFolderPath(struct _GUID,class
llvm::SmallVectorImpl<char> &)" (?
getKnownFolderPath#path#sys#llvm##YA_NU_GUID##AEAV?$SmallVectorImpl#D#3##Z)
build\test.exe : fatal error LNK1120: 1 unresolved externals
Which library do I have to link to for this function to be defined? I can see the implementation in the code I built from. Do I need to build llvm in a particular way for this to be exported?
EDIT:
It turns out that I needed to read the clang-cl documentation a little better where it says:
To enable clang-cl to find system headers, libraries, and the linker when run from the command-line, it should be executed inside a Visual Studio Native Tools Command Prompt or a regular Command Prompt where the environment has been set up using e.g. vcvars32.bat.
It turns out that this solves my problem. I was a little confused because clang-cl seems to resolve the sdk include and tool paths automatically, but not the lib paths. I also don't want to use CMD to drive clang so I was using bash where I can't run vcvar32.bat easily. I solved my problem by essentially duplicating what vcvar32.bat is doing to the $PATH, $INCLUDE, $LIB and $LIBPATH environment variables and adding Ole32.Lib as a parameter to clang-cl. It then works like a charm.
You're missing the CoTaskMemFree symbol. A quick look on the Internet suggests you'll need the Ole32 system library on your link line.
I don't have access to a Windows machine to test on, but on my computer, I can run llvm-config --system-libs and it pulls in the all the necessary things. After adding using namespace llvm; and adding a stub main function, I can easily build this example with (on OSX):
c++ `llvm-config --cxxflags` main.cpp `llvm-config --ldflags --system-libs --libs core support`
I often recommend just specifying --libs rather than guessing what you'll need, but your choice.

Calling a method in a static library

I'm trying to write a C standard library from scratch on OSX with gcc. When I try to include a header file from my library in my test program, I get the error that it isn't defined. I try to use the -nostdlib flag but I still can't include my file.
My test program:
#include <math.h>
#include <bool.h>
#include <ctype.h>
#include <string.h>
#include <io.h>
int main(){
int x = sin(0.5);
int y = pow(2,3);
int z = abs(12);
myiofunction(7);
exit(0);
}
math.h,bool.h,ctype.h,string.h, and io.h are defined in my library. What am I doing incorrectly?
EDIT:
The error message that I am getting is:
helloTest.c:10:10: fatal error: 'bool.h' file not found
Header files aren't compiled into a static library. They have to be available to both library and program.
Therefore, when compiling your program, make sure to specify the -I options to let the compiler find your library's header files.
In order for it to use your own standard library as well, you have to use the -I option to include your library:
gcc -nostdlib -I/path/to/my/headers/ ...
So if the headers for those files were located in ./include, you'd compile with:
gcc -nostdlib -I./include/ ....
Of course you need to provide the object code for these functions at some point. Then you can link them all together using ld with -lgcc to resolve any internal GCC subroutines.
GCC Linking Options: https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
You need to write :
#include "bool.h"
Check that out:
Include Syntax
If you use it won't work anyway. You have to typed as "bool.h"
and the other thing is -l option.
Check it out : https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
If you specifiy the default location : -R [PATH]
The library to include is
#include <stdbool.h>

Problems linking to FFMPEG library in Visual Studio 2010

I have cross-compiled FFMPEG from Debian using the mingw32 toolchain. The result of the compilation is a set of .a files. When I try to use them in my project I get linker errors, concretely the following ones:
1>RTSPCapture.obj : error LNK2019: unresolved external symbol _avformat_free_context referenced in function ...
1>RTSPCapture.obj : error LNK2019: unresolved external symbol _avio_close referenced in function ...
1>RTSPCapture.obj : error LNK2019: unresolved external symbol _avcodec_close referenced in function ...
(and much more...)
I have already included the header files like this:
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
}
And I use the .a files like this:
#pragma comment(lib, "libavcodec.a")
#pragma comment(lib, "libavformat.a")
#pragma comment(lib, "libavutil.a")
May I know why I am still getting linker errors? Best regards,
EDIT: I have realized that this is not possible. So, what should I do to use FFMPEG library in my MSVC2010 project taking into account that I can't compile ffmpeg in Windows? it seems to be REALLY difficult...
GCC (the compiler used by MinGW) does not have the #pragma used by VisualC++ to add libraries. You have to manually add the libraries when linking using the -l option:
$ gcc objectfile1.o objectfile2.o -o executable -lavcodec -lavformat -lavutil
Finally I realized that mingw compiles libs could not be linked in VS2010 native applications.