Making a simple app that logs and reads in command line arguments with Visual Studio 2010 Express, google glog and google gflags? - visual-c++

I've written the following simple program:
#include "stdafx.h"
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <ostream>
int _tmain(int argc, char* argv[])
{
google::InitGoogleLogging(argv[0]);
LOG(INFO) << "Found";
return 0;
}
I checked out google-glog from here: http://code.google.com/p/google-glog/source/checkout
And I've checked out google-gflags from here: http://code.google.com/p/google-gflags/
I have all three of these projects in Visual Studio 2010 Express, all under the same solution:
Solution
GoogleLibsTest
libgflags
libglog
When I compile it, I get the following error:
1>------ Build started: Project: GoogleLibsTest, Configuration: Debug Win32 ------
1>GoogleLibsTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall google::LogMessage::~LogMessage(void)" (__imp_??1LogMessage#google##QAE#XZ) referenced in function _wmain
1>GoogleLibsTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall google::LogMessage::stream(void)" (__imp_?stream#LogMessage#google##QAEAAV?$basic_ostream#DU?$char_traits#D#std###std##XZ) referenced in function _wmain
1>GoogleLibsTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall google::LogMessage::LogMessage(char const *,int)" (__imp_??0LogMessage#google##QAE#PBDH#Z) referenced in function _wmain
1>GoogleLibsTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl google::InitGoogleLogging(char const *)" (__imp_?InitGoogleLogging#google##YAXPBD#Z) referenced in function _wmain
1>C:\Users\leeand00\Desktop\glogNgflagsTest\GoogleLibsTest\Debug\GoogleLibsTest.exe : fatal error LNK1120: 4 unresolved externals
========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========
I've done several things to try and fix this including:
In the Solution Property page Selecting Common Properties Project>Dependencies and setting the GoogleLibsTest to depend on the other two projects.
In the GoogleLibsTest Property page
Adding libgflags-debug.lib libglog_static.lib to the Configuration Properties>Linker>Input>Additional Dependencies list.
In Configuration Properties>VC++ Directories I added the directory containing libgflags-debug.lib and libglog_static.lib to the list of library directories.
In Configuration Properties>C/C++>General>Additional Include Directories added the paths to the <glog-base-dir>\src\windows (since this is where the header files are for glog)
In Configuration Properties>C/C++>General>Additional Include Directories added the paths to the <gflags-base-dir>\src\windows (since this is where the header files are for gflags)
For some reason it is looking for a dll file (I don't know why that is)
Is there anything else I'm missing?

It seems that you want to static link to glog, but forget to define "GOOGLE_GLOG_DLL_DECL=" macro, just check out logging_unittest_static project shipped with glog.
Though I think there're some other problems when using glog with gflags on Windows. Check out this link

Assuming that your project already has the "Additional Include Directories" set to src/windows of the GLOG project folder, then check the following:
1) Make sure that both GLOG and your app is compiled in either 32 or 64 bit (as of this date GLOG only seems to compile 64 bit in release mode)
2) Make sure that libglog.dll is in your system path
3) Make sure that libglog.lib is set in your project's "Additional Dependencies" (under Linker->Input)
4) Make sure that the path to libglog.lib is set in your project's "Additional Library Directories" (under Linker->General)

Related

Updating to new ubuntu server breaks g++ build with a bunch of c++/9 errors?

We are moving to a new Ubuntu server (newer Ubuntu version) and the old build is not working. We get tons of errors from c++/9. A couple examples below. Any idea how I get the build (a single .cpp file) to work using g++?
/usr/include/c++/9/array: In function 'bool std::operator<(const std::array<_Tp, _Nm>&, const std::array<_Tp, _Nm>&)':
/usr/include/c++/9/array:264:19: error: 'lexicographical_compare' is not a member of 'std'; did you mean 'lexicographical_compare'?
264 | return std::lexicographical_compare(__a.begin(), __a.end(),
| ^~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/memory:62,
from /usr/include/unicode/localpointer.h:45,
from /usr/include/unicode/uenum.h:23,
from /usr/include/unicode/ucnv.h:53,
from /usr/include/libxml2/libxml/encoding.h:31,
from /usr/include/libxml2/libxml/parser.h:810,
from /usr/include/libxml2/libxml/xmlerror.h:10,
from /usr/include/libxml2/libxml/xpath.h:26,
from /usr/local/include/libcsoap-1.1/libcsoap/soap-xml.h:27,
from /usr/local/include/libcsoap-1.1/libcsoap/soap-env.h:29,
from /usr/local/include/libcsoap-1.1/libcsoap/soap-client.h:27,
from myapp.cpp:6318:
/usr/include/c++/9/bits/stl_algobase.h:1277:5: note: 'lexicographical_compare' declared here
1277 | lexicographical_compare(_II1 __first1, _II1 __last1,
| ^~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/9/array: In member function 'void std::array<_Tp, _Nm>::fill(const value_type&)':
/usr/include/c++/9/array:117:14: error: 'fill_n' is not a member of 'std'; did you mean 'fill_n'?
117 | { std::fill_n(begin(), size(), __u); }
| ^~~~~~
In file included from /usr/include/c++/9/memory:62,
from /usr/include/unicode/localpointer.h:45,
from /usr/include/unicode/uenum.h:23,
from /usr/include/unicode/ucnv.h:53,
from /usr/include/libxml2/libxml/encoding.h:31,
from /usr/include/libxml2/libxml/parser.h:810,
from /usr/include/libxml2/libxml/xmlerror.h:10,
from /usr/include/libxml2/libxml/xpath.h:26,
from /usr/local/include/libcsoap-1.1/libcsoap/soap-xml.h:27,
from /usr/local/include/libcsoap-1.1/libcsoap/soap-env.h:29,
from /usr/local/include/libcsoap-1.1/libcsoap/soap-client.h:27,
from myapp.cpp:6318:
I setup a test.cpp and included the same headers as myapp.cpp and it worked. Weird, so I then tried a few #define items included in myapp.cpp and tried again, worked. Now in myapp.cpp the include files for the soap-client.h was down in the middle of the code for CGI support. I moved the #include for that up to the top with the other #include items and it compiled fine.
My only thought is there must have been something in the code, either a function, typedef or #define that conflicted with some of the standard headers?
Anyway, if you run in to something like that, here is one thing to check.

Register C++ version of Rcpp function and use it within the other Rcpp function in a new package

I have a package hpa that has some functions written in Rcpp. I want to use some of these functions within my new R-package. It is necesseraly to use this functions in "Rcpp form" in order to avoid perfomance penalty so I can't to export them in a usual way.
I have found a similar questions. Following the answer of Dirk Eddelbuettel I have investigated this file and written the following code (within init.c file that has been placed in the src folder) in hope to make polynomialIndex function (from hpa package) become available (in Rcpp i.e. C++ form) for Rcpp functions of other pacakges (including my new one):
#include <Rconfig.h>
#include <Rinternals.h>
#include <R_ext/Rdynload.h>
#include "polynomialIndex.h"
/* definition of functions provided for .Call() */
static const R_CallMethodDef callMethods[] = {
{ "polynomialIndex", (DL_FUNC) &polynomialIndex, 1 },
{ NULL, NULL, 0 }
};
/* functions being called when package is loaded -- used to register */
/* the functions we are exporting here */
void R_init_RApiSerialize(DllInfo *info) {
/* used by external packages linking to internal serialization code from C */
R_RegisterCCallable("hpa", "polynomialIndex",
(DL_FUNC) &polynomialIndex);
R_registerRoutines(info,
NULL, /* slot for .C */
callMethods, /* slot for .Call */
NULL, /* slot for .Fortran */
NULL); /* slot for .External */
R_useDynamicSymbols(info, TRUE); /* controls visibility */
}
Unfortenatelly when I am trying to build hpa package the following error message arise:
/mingw64/bin/gcc -I"C:/R/R-41~1.0/include" -DNDEBUG -I'C:/R/R-4.1.0/library/Rcpp/include' -I'C:/R/R-4.1.0/library/RcppArmadillo/include' -I'C:/R/R-4.1.0/library/RcppParallel/include' -O2 -Wall -std=gnu99 -mfpmath=sse -msse2 -mstackrealign -c init.c -o init.o
In file included from C:/R/R-4.1.0/library/Rcpp/include/Rcpp/r/headers.h:66,
from C:/R/R-4.1.0/library/Rcpp/include/RcppCommon.h:30,
from C:/R/R-4.1.0/library/RcppArmadillo/include/RcppArmadilloForward.h:26,
from C:/R/R-4.1.0/library/RcppArmadillo/include/RcppArmadillo.h:31,
from polynomialIndex.h:4,
from init.c:4:
C:/R/R-4.1.0/library/Rcpp/include/Rcpp/platform/compiler.h:100:10: fatal error: cmath: No such file or directory
#include <cmath>
^~~~~~~
compilation terminated.
make: *** [C:/R/R-41~1.0/etc/x64/Makeconf:238: init.o] Error 1
It seems to be associated with the fact that polynomialIndex.h file includes <RcppArmadillo.h>. The file itself looks as follows:
#ifndef hpa_polynomialIndex_H
#define hpa_polynomialIndex_H
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace RcppArmadillo;
NumericMatrix polynomialIndex(NumericVector pol_degrees,
bool is_validation);
String printPolynomial(NumericVector pol_degrees,
NumericVector pol_coefficients,
bool is_validation);
#endif
Then I have tried to remove polynomialIndex.h from init.c and to declare polynomialIndex directly inside init.c file. Unfortunatelly it results into the other error message:
/mingw64/bin/gcc -I"C:/R/R-41~1.0/include" -DNDEBUG -I'C:/R/R-4.1.0/library/Rcpp/include' -I'C:/R/R-4.1.0/library/RcppArmadillo/include' -I'C:/R/R-4.1.0/library/RcppParallel/include' -O2 -Wall -std=gnu99 -mfpmath=sse -msse2 -mstackrealign -c init.c -o init.o
** using staged installation
** libs
/mingw64/bin/g++ -std=gnu++11 -shared -s -static-libgcc -o hpa.dll tmp.def ParallelFunctions.o RcppExports.o hpaBinary.o hpaML.o hpaMain.o hpaSelection.o hpaValidation.o init.o normalMoments.o polynomialIndex.o spline.o -LC:/R/R-41~1.0/bin/x64 -lRlapack -LC:/R/R-41~1.0/bin/x64 -lRblas -lgfortran -lm -lquadmath -LC:/R/R-41~1.0/bin/x64 -lR
C:/rtools40/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: init.o:init.c:(.text+0x8): undefined reference to `polynomialIndex'
C:/rtools40/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: init.o:init.c:(.rdata+0x28): undefined reference to `polynomialIndex'
C:/rtools40/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: init.o:init.c:(.rdata$.refptr.polynomialIndex[.refptr.polynomialIndex]+0x0): undefined reference to `polynomialIndex'
Please help me to figure out these problems. In the end I want to be able to use polynomialIndex function within my new package. According to the information I have found it should look something like this (simplifed expample):
// [[Rcpp::depends(hpa)]]
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector newFunc(NumericVector pol_degrees,
bool is_validation) {
static SEXP(*polynomialIndex)(Rcpp::NumericVector, bool) = NULL;
polynomialIndex = (SEXP(*)(Rcpp::NumericVector, bool)) R_GetCCallable("hpa", "polynomialIndex");
NumericVector result = polynomialIndex(pol_degrees, is_validation);
return(result);
}
P.S. This question is also similar to this one but does not resolve my problem.
This has been discussed before, and I would urge you to study these other questions and experiment with their answers.
Here you appear to have a cross-over from a C compilation (started by gcc) touching a file in which you crossed over to C++. Which, plainly stated, you cannot do for C compilation.
R offers C interfaces only. Rcpp helps you by autogenerating complying interface files. If you want to extend/alter them you have to play by the rules.
Wrapping C++ code in (simpler, more portable, cross-compiler, ...) C interfaces is a decades old trick. You likely find many resources for it.
Following Dirk Eddelbuettel's suggestion I have made additional search concerning this problem. Unfortunatelly I have found an extremely simple solution.
First, I have deleted init.c file.
Second, I have added the following line of code to all .cpp files of hpa package.
// [[Rcpp::interfaces(r, cpp)]]
Third I have added the following code to the description file of my new package in order to link it to hpa package (I have made it before the solution has been found but in order to provide a full reciepe it seems reasonable to add this information).
Imports: Rcpp (>= 1.0.6), hpa (>= 1.2.1)
Depends: hpa (>= 1.2.1)
LinkingTo: Rcpp, RcppArmadillo, hpa
Fourth, by the same reasons I have added the following line of code to the namespace file:
import(hpa)
Fifth, I have compiled hpa package (as usual) and have found a new folder named inst. Inside this folder there is a folder include. In this folder I have found a new file hpa.h. So I have simply included this file into the code and simplified the call to the function to hpa::polynomialIndex(...). So the resulting (succesfully working!) code is as follows:
// [[Rcpp::depends(hpa)]]
#include <RcppArmadillo.h>
#include <hpa.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector newFunc(NumericVector pol_degrees,
bool is_validation) {
NumericVector result = hpa::polynomialIndex(pol_degrees, is_validation);
return(result);
}
P. S. It was informative to investigate the file hpa\inst\include\hpa_RcppExports.h to understand how does [[Rcpp::interfaces(r, cpp)]] resolves the problem.

Error: conflicting types when trying to make a simple syscall

I'm brand new to Linux programming and I'm trying to implement a simple system call loosely following this guide: https://medium.com/anubhav-shrimal/adding-a-hello-world-system-call-to-linux-kernel-dad32875872. In my linux kernel directory, I created a new directory called my_syscall. Within that directory, I created my_syscall.c. Here is my_syscall.c
#include <linux/syscalls.h>
#include <linux/kernel.h>
asmlinkage long sys_my_syscall(int i) {
prink(KERN_INFO "This is the system call.");
return(0);
}
I then created a Makefile in the my_syscall directory with a single line:
obj-y := my_syscall.o
I then edited this line in the Makefile in the kernel directory to be:
core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ my_syscall/
Then, in the directory linux-5.4.15/arch/x86/entry/syscalls, I edited the syscall_64.tbl to include the following line at the very end:
548 64 my_syscall sys_my_syscall
Finally, in the directory linux-5.4.15/include/linux, I edited the syscalls.h file to include this line before the #endif:
asmlinkage long sys_my_syscall(int i);
Now, when I run the command sudo make, I run into the following error soon after:
./arch/x86/include/generated/asm/syscalls_64.h:2664:19: error: conflicting types for 'sys_my_syscall'
__SYSCALL_64(548, sys_my_syscall, )
arch/x86/entry/syscall_64.c:18:60: note: in definition of macro '__SYSCALL-64'
#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *);
In file included from arch/x86/entry/syscall_64.c:7:0:
./include/linux/syscalls.h:1423:17: note: previous declaration of 'sys_my_syscall' was here
asmlinkage long sys_my_syscall(int i);
^
make[3]: *** [arch/x86/entry/syscall_64.o] Error 1
make[2]: *** [arch/x86/entry] Error 2
make[1]: *** [arch/x86] Error 2
make: *** [sub-make] Error 2
I have no idea how to approach this error. With a conflicting types error, I would think I declared the syscall differently in someplace, but in both my_syscall.c and the syscalls.h files, the declaration is the same. These were the only two files where the syscall is declared, but it is also named within syscall_64.tbl and it seems like this is where linux is trying to point me towards. However, I don't see what's wrong with how I declared it in the table as I followed the guide directly. Any help with this would be greatly appreciated!
Info:
Kernel version: 5.4.15
Linux Distribution: Ubuntu 14
I just changed the location where the syscall number is defined in syscall_64.tbl.
Instead of this:
548 64 my_syscall sys_my_syscall
I wrote this:
436 common my_syscall __x64_sys_my_syscall
Screen Capture of my configuration
It worked out.
I'm doing something similar and got the exact same error.
What fixed the error for me is changing the last part of the syscall_64.tbl table entry from "sys_my_syscall" to "__x64_sys_my_syscall". If you scroll up, other entries have the same prefix. The kernel started compiling after I made that change.
I eventually gave up on trying to implement this in kernel 5. Unfortunately, none of the other solutions resulted in my kernel compiling. I rolled back my kernel and followed the steps here. This resulted in the system call working correctly. I'm not sure how to make this function in kernel 5+.
#include <linux/syscalls.h>
#include <linux/kernel.h>
SYSCALL_DEFINE1(my_syscall, int, i)
{
printk(KERN_INFO "This is the system call (param %d).\n", i);
return(0);
}
For kernel 5, try deleting "sys_" before "my_syscall" and try. It worked for me
Some architectures (including x86-64) use syscall wrappers to call the real syscall handler. To define the real syscall handler and its wrappers (for architectures that use syscall wrappers), use one of the SYSCALL_DEFINE<n> macros before the body of the syscall handler. The parameters of the SYSCALL_DEFINE<n> macros are the function name, followed by <n> pairs of ``type, param'' for the function parameters.
Your sys_my_syscall syscall handler function has one parameter, so use the SYSCALL_DEFINE1 macro before the body of the function:
#include <linux/syscalls.h>
#include <linux/kernel.h>
SYSCALL_DEFINE1(sys_my_syscall, int, i)
{
printk(KERN_INFO "This is the system call (param %d).\n", i);
return(0);
}

Compilation of detours on vs2012 (Windows 8.1)

Using the visual studio 2012 command tools (i.e. in the 'native tools command prompt' command console) I have run vcvars32.bat, and navigated to *c:\program file(x86)\Microsoft Research\Detours Express 3.0*.
On running nmake in this directory, it begins building successfully, however it then exits with the error:
cl /nologo /nologo /Zi /MT /Gm- /W4 /WX /Od /DDETOURS_BITS=32 /I..\..\include /Gs /DDETOURS_X86=1 /DDETOURS_32BIT=1 /D_X86_ /DDETOURS_OPTION_BITS=64 /Fdobj.X86\vc.pdb /Foobj.X86\member.obj /c member.cpp
member.cpp
member.cpp(88) : error C2440: 'type cast' : cannot convert from 'void (__thiscall CMember::* )(void)' to 'PBYTE &'
Reason: cannot convert from 'overloaded-function' to 'PBYTE *'
There is no context in which this conversion is possible
member.cpp(90) : error C2440: 'type cast' : cannot convert from 'void (__thiscall CDetour::* )(void)' to 'PBYTE &'
Reason: cannot convert from 'overloaded-function' to 'PBYTE *'
There is no context in which this conversion is possible
// error repeated member.cpp lines 105, 120, 122.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\BIN\nmake.exe"' : return code '0x2'
Stop.
Not sure how to move on with this error. I also attempted to:
set DETOURS_TARGET_PROCESSOR=X86
and then "nmake clean" followed by a new "nmake" - however this results in the same error.
as specified in the title, I am building with vs2012, on a windows 8.1 box (x64).
thank you
ok, so i solved it, so i thought i'd post the answer if anyone else finds it useful.
I've done this by trial and error, so I would still like someone to come on and explain why/what this error is and what caused it etc.
however, here are the changes i made to get it to compile:
#if (_MSC_VER < 1310)
pfTarget = CMember::Target;
pfMine = CDetour::Mine_Target;
Verify("CMember::Target", *(PBYTE*)&pfTarget);
Verify("*CDetour::Real_Target", *(&(PBYTE&)CDetour::Real_Target));
Verify("CDetour::Mine_Target", *(PBYTE*)&pfMine);
#else
//Verify("CMember::Target", (PBYTE)(&(PBYTE&)CMember::Target));
//Verify("*CDetour::Real_Target", *(&(PBYTE&)CDetour::Real_Target));
//Verify("CDetour::Mine_Target", (PBYTE)(&(PBYTE&)CDetour::Mine_Target));
pfTarget = &CMember::Target;
pfMine = &CDetour::Mine_Target;
Verify("CMember::Target", *(PBYTE*)&pfTarget);
Verify("*CDetour::Real_Target", *(&(PBYTE&)CDetour::Real_Target));
Verify("CDetour::Mine_Target", *(PBYTE*)&pfMine);
#endif
my changes are in the 2nd half 'else' statement, original code is commented out.
For each error (relevant line numbers in original question) - I commented out what was there, copied and pasted from the 1st half "if" section", but changed from "pfTarget = CMember::Target;" to "pfTarget = &CMember::Target;" (based on instruction from the compiler).
seems to be two different issues, first taking the wrong path in the if/else block (_MSC_VER supposed to be set somewhere and isn't?) and secondly the required change from CMember::Target to &CMember::Target.
thanks
The solution provided by wibble didn't work for me but since the compiler errors are only occurring when compiling the samples (after MS Detours compiled successfully), the errors aren't important anymore if you just want to use the library.

Unresolved external symbol

I have two WIN32 DLL projects in the solution, main.dll should call a function in mgn.dll.
mgn.dll has mgn.h header file:
#ifdef MGN_EXPORTS
#define MGN_API __declspec(dllexport)
#else
#define MGN_API __declspec(dllimport)
#endif
extern "C" bool MGN_API AttachMGN(void);
and mgn.cpp source file:
#include "stdafx.h"
#include "mgn.h"
MGN_API bool AttachMGN(void)
{
...
}
main.dll calls AttachMGN function from one of the source file:
#include "stdafx.h"
#include "..\mgn\mgn.h"
bool CreateClient()
{
return ::AttachMGN();
}
mgn.dll compiles successfully. main.dll doesn't show any errors in VS text editor, I can navigate using "Go To Definition" function. However during build I get the error:
error LNK2019: unresolved external symbol __imp__AttachMGN referenced in function "bool __cdecl CreateClient(void)" (?CreateClient##AW4XZ)
Both DLLs compile into the same folder. DependencyWalker shows the function AttachMGN as exported. Main project has a dependency set to Mgn project, if that matters.
I believe that I simply have overlooked something....
Thanks in advance.
You probably just forgot to add MGN.lib to your link arguments for main.dll
Is your mgn.lib linked with the main? By the sound of it, it looks as if main cannot find the lib file to link against the DLL.

Resources