I'm trying to write a wrapper for a C++ function I've written, making use of the Point Clouds Library (PCL). This is my first try interfacing R and C++, so I apologise if any solution is too trivial. My goal is to make a few functions available for myself and my colleagues directly in R, on mac and windows. My example function cloudSize is included at the bottom of the text. I will try to be as clear as possible.
I've installed PCL with the vcpkg package manager for winx64 at C:\src\vcpkg\vcpkg.
This is added to my Environmental Variable Path for my user.
I created an empty R-package with Rcpp.package.skeleton():
C:/User/csvi0001/Desktop/GitHub/RPCLpackage/PCLR
PCL is a massive library, but thankfully modular,and so I only #include the headers that are needed to compile the executable: pcl/io/pcd_io.h, pcl/point_types.h, pcl/registration/icp.h.
Now, since I'd like this to work on more than one OS - and therefore compile on install (?) - I should use a dynamic library? I'll presume that the person installing my package already has a compiled copy of pcl. However, I do not know how to find a flag showing that pcl is installed - how do I find these for inclusion in Makevars(?). CMake must find them when testing the C++ function in VSCode after adding an include path. In lieu of this:
I copy the pcl folder installed by vcpkg to ./src . When I tried copying all the .h files, they seemed to lose track of one another as they refer to eachother through which module they are placed in, e.g. <pcl/memory.h> cannot be found if memory.h is placed directly in ./src. However, flattening the structure of the modules means that every single dependency and #include must be manually changed, in some cases there are also files with the same name in different folders. e.g. pcl/kdtree.h and pcl/search/kdtree.h. After this, it must be done again when replacing < > with " " for each header.
Is there any way of telling Rcpp that the library included in /src is structured?
I'm working on Win 10 winx64.
Since I'm making use of the depends RcppEigen and BH; and I must have C++14 or higher (choice: C++17) I add to my DESCRIPTION file:
LinkingTo: Rcpp, RcppEigen, BH
SystemRequirements: C++17
My actual C++ function:
//PCL requires at least C++14
//[[Rcpp::plugins(cpp17)]]
//[[Rcpp::depends(RcppEigen)]]
//[[Rcpp::depends(BH)]]
#include <Rcpp.h>
#include <iostream>
#include "pcl/io/pcd_io.h"
#include "pcl/point_types.h"
#include "pcl/registration/icp.h"
//[[Rcpp::export]]
int cloudSize(Rcpp::DataFrame x)
{
pcl::PointCloud<pcl::PointXYZ> sourceCloud;
for(int i=0;i<x.nrows();i++)
{
sourceCloud.push_back(pcl::PointXYZ(x[0][i],x[1][i],x[2][i])); //This way of referring to elements in a Rcpp::DataFrame may be erroneous.
}
int cloudSize = sourceCloud->size();
return (cloudSize);
}
That is a non-trivial question. In the simplest case, use a 'hook' offered by configure and configure.win to pre-build a (static) library you ship in your sources and then link your package to that.
That said, the Writing R Extensions manual and/or the CRAN Repository Policy (both of which are the references here) expressed more of a preference for an external library -- which may not be an option here if PCL is too exotic.
As the topic comes up with Rcpp, I wrote a short paper about it (at arXiv here) which is also included as a vignette in the package. It requires a few pages to cover the common cases but even then it cannot cover all.
Your main source of reference may be CRAN. The are lots of packages in this space. A few of mine use external libraries, I contributed to package nloptr which uses a hybrid approach ("use system library if found, else build") and some like httpuv always build (a small-ish library).
I can't, for the love of God, to static link the ZLIB libs. I have been struggling for a couple hours now with no success. Well, I have followed this tutorial and successfuly compiled both zlibstat.lib and zlibwapi.lib for 32 bits. After setting up my project to use the ZLIB folder with the libraries (Linker > General > Additional Library Directories) and setting zlibwapi.lib (only) as an dependency (Linker > Input > Additional Dependencies) I got it to work, however, that was a dynamic link (I need to distribute my application with the ZLIB dll). I usually use dynamic linking on Debug and static on Release.
I have tried looking for what the hell is the zlibstat.lib and whats it used for, if not for static linking, assuming the "stat" suffix.
Are there any preprocessor to be added into my project, something like ZLIB_STATIC or something, to use static linking of ZLIB or should I have never removed the ZLIB_WINAPI from the zlibstat project, just like the above link told me to do? Is it impossible to static link ZLIB (then, whats zlibstat.lib for?)?
I am pretty lost. Any help is GREATLY appreciated.
Edit (Extra information):
Errors:
error LNK2001: unresolved external symbol _inflateInit_#12
error LNK2001: unresolved external symbol _inflate#8
error LNK2001: unresolved external symbol _inflateEnd#4
Linking:
Unlike the dynamic link (that worked) where I added zlibwapi.lib as a dependency, for the static linking I'm trying to achieve I added zlibstat.lib as a dependency instead! No other libs were added!
This question might look like this (kind of).
I have finally managed to solve my problem. For those that end up in such a problem, heres how to solve it:
If you followed the tutorial in my first post, you would have removed ZLIB_WINAPI from the zlibstat project's Preprocessor. However, after setting up my own project (setting ZLIB dependencies path, LIB dependencies libraries etc) that uses ZLIB, I 'accidently' included/defined the damned ZLIB_WINAPI macro in the header file I'm using ZLIB, right before including "zlib.h".
One curious thing about this is that when launching the app on debug mode (which was using dynamic linking), everything succeeded and worked like a charm, without any warnings or whatsoever, HOWEVER, on release mode (which was using the static linking), it crashed.
So, to clear things up, the tutorial tells us to remove the ZLIB_WINAPI preprocessor from the zlibstat project, which produces the static lib, whilst the zlibvc project has the ZLIB_WINAPI in its preprocessor. In other words, that means that if we're using different linkings for each configuration (debug/release), we have to add the ZLIB_WINAPI macro or not!
Define the ZLIB_WINAPI macro before including "zlib.h" if youre using dynamic linking (zlibwapi.lib) and that the zlibvc project remains unmodified (assuming you correctly followed the tutorial from the link above) and do not define it if you removed ZLIB_WINAPI from the zlibstat project (like the tutorial tell us to)!
One helpful macro I used on my own project is as follows:
// Since we used dynamic linking for debug, we have to define the ZLIB_WINAPI
#if defined(_WIN32) && defined(_DEBUG)
#define ZLIB_WINAPI
#endif
#include <zlib.h>
Things got really confusing and I really hope I was clear enough.
I am getting this single error when I am linking my project,
COMMUNICATION.obj : fatal error LNK1179: invalid or corrupt file:
duplicate COMDAT '_IID_IXMLDOMImplementation'
What is the source of the problem?
This is a tricky one.
The issue is that the symbol(s)-generated is too-long, and an ambiguity exists:
//...
void MyVeryLongFunctionNameUnique_0(void);
void MyVeryLongFunctionNameUnique_1(void);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// (example max-symbol-length-seen-by-linker)
In this case, the linker "sees" these two functions as the "same", because the part that makes them "unique" is longer-than-the-max-symbol length.
This can happen in at least three cases:
Your symbol names are "too-long" to be considered unique to the linker, but may have been fine for the compiler (such as when you expand-out from many nested templates)
You did some "trickery" that is invalid C++, and it passed the compiler, but you now have an invalid *.obj, and it chokes the linker.
You specified duplicate "unnamed" classes/structs, and the linker cannot resolve them.
===[UPDATE]===, It's not your fault, it's an internal problem with the compiler and/or linker (see below for possible work-arounds).
Depending on the issue (above), you can "increase" your symbol-length (by limiting-your-decrease-of-symbol-length), or fix your code to make it valid (unambiguous) C++.
This error is (minimally) described by Microsoft at:
http://msdn.microsoft.com/en-us/library/cddbs9aw(v=vs.90).aspx
NOTE: This max-symbol-length can be set with the /H option, see: http://msdn.microsoft.com/en-us/library/bc2y4ddf(v=vs.90).aspx
RECOMMEND: Check to see if /H is used on your command-line. If it is, delete it (do not specify max-symbol-length, it will default to 2,047, the /H can only DECREASE this length, not increase it).
However, you probably triggered it through the /Gy option (function-level-linking), which was probably implied through one of /Z7, /Zi, or /ZI: http://msdn.microsoft.com/en-us/library/958x11bc(v=vs.90).aspx
One MSDN thread that talks about this issue is:
http://social.msdn.microsoft.com/Forums/en-US/vcmfcatl/thread/57e3207e-9fab-4b83-b264-79a8a717a8a7
This thread suggests that it's possible to trigger this issue with "invalid-C++-code-that-compiles" (you get your *.obj), but that invalid-*.obj chokes the linker (this example attempts to use main as both a function and as a template):
http://www.cplusplus.com/forum/lounge/46361/
===[UPDATE]===
I should have said this before, because I suspected, but I now have more information: It might not be your fault, there seems to be an issue in the compiler and/or linker that triggers this error. This is despite the fact that the only common denominator in all your failed relationships is you.
Recall that the "above-list" applies (it MIGHT be your fault). However, in the case where, "it's not your fault", here's the current-running-list (I'm confident this list is NOT complete).
There is an internal error/corruption in your *.ilk file (intermediate-link-file). Delete it and rebuild.
You have /INCREMENTAL turned on for linking, but somehow that incremental-linking is not working for your project, so you should turn it off and rebuild (Project-Properties=>Configuration Properties=>Linker=>General=>Enable Incremental Linking [set to "No" (/INCREMENTAL:NO)]
There's a problem with "Optimization" for "COMDAT Folding" in your use. Your can "Remove Redundant COMDATs" by going to Project Proerties=>Configuration Properties=>Linker=>Optimization=>Enable COMDAT Folding, set to "Remove Redundant COMDATs (/OPT:ICF)
Here's an interesting thread from a guy who sometimes can link, and sometimes not, by commenting in/out a couple lines of code. It's not the code that is the problem -- he just cannot link consistently, and it looks like the compiler and/or linker has an internal problem under some obscure use case:
http://www.pcreview.co.uk/forums/fatal-error-lnk1179-t1430593.html
Other observations from a non-trivial web search:
this problem appears to be non-rare
it seems to be related to some form of template<> use
others seem to see this problem with "Release" build when it did not have this problem with "Debug" build (but it is also seen on the "Debug" build in many cases)
if the link "fails" on one machine, it may "succeed" on another build machine (not sure why, a "clean-build" appears to have no effect)
if you comment in/out a particularly significant couple-lines-of-code, and finish your build, and keep doing this until all the code is un-commented again, your link may succeed (this appears to be repeatable)
if you get this error with MSVC2008, and you port your code to MSVC2010, you will still get this error
===[PETITION TO THE GOOD PEOPLE OF THE WORLD]===
If you have other observations on this error, please list them below (as other answers, or as comments below this answer). I have a similar problem, and it's not my fault, and none of these work-arounds worked for me (although they did appear to work for others in their projects in some cases).
I'm adding a bounty because this is driving me nuts.
===[UPDATE+2]===
(sigh), Here's more things to try (which apparently work for others, but did not work for me):
this guy changed his compile settings, and it worked (from thread at http://forums.codeguru.com/showthread.php?249603.html):
Project->Settings->C++ tab, Debug cathegory: Inline function expansion: change from 'None' to 'Only _inline'.
the above thread references another thread where the had to re-install MSVC
it is possibly related to linking modules with "subtle-differences" in possibly-incompatible compiler and/or link switches. Check that all the "contributing libs" are built with the exact same switches
Here's some more symptoms/observations on this error/bug:
list(s) for above issues still apply
the issue seems to "start-showing-up" with MSVC2005, and continues with the same behavior for MSVC2008 and MSVC2010 (error still occurs after porting code to newer compilers)
restarting IDE, rebooting machine doesn't seem to work for anybody
one guy said an explicit "clean" followed by a recompile worked for him, but many others say it did not work for them
is often related to "incremental linking" (e.g., turn it off)
Status: No joy.
===[UPDATE+3 : LINK SUCCESS]===
Super-wacky-makes-no-sense fix to successfully link discovered!
This is a variation on (above), where you "fiddle-with-the-code-until-the-compiler-and/or-linker-behaves". NOT GOOD that one might need to do this.
Specific single linker-error (LNK1179) was for MyMainBody<>():
#include "MyClassA.hpp"
#include "MyClassB.hpp"
#include "MyClassC.hpp"
#include "MyClassD.hpp"
#include "MyMainBody.hpp"
int main(int argc, char* argv[])
{
// Use a function template for the "main-body",
// implementation is "mostly-simple", instantiates
// some local "MyClass" instances, they reference
// each other, and do some initialization,
// (~50 lines of code)
//
// !!! LNK1179 for `MyMainBody<>()`, mangled name is ~236 chars
//
return MyMainBody<MyClassA,MyClassB,MyClassC,MyClassD>(argc,argv);
}
THE FIX:
Convert MyMainBody<>() from a "template<>" to an explicit function, LINK SUCCESS.
THIS FIX SUX, as I need the EXACT-SAME-CODE for other types in other utilities, and the MyMainBody<>() implementation is non-trivial (but mostly simple) instantiations-and-setups that must be done in a specific way, in a specific order.
But hey, it's a temporary work-around for now: Confirmed on MSVC2008 and MSVC2010 compilers (same LNK1179 error for each, successful link on each after applying the work-around).
THIS IS A COMPILER AND/OR LINKER ERROR, as the code is "simple/proper-C++" (not even C++11).
So, I'm happy (that I got a link after suffering full-time for 2+weeks). But, disappointed (that the compiler and/or linker has a STUPID GLARING PROBLEM with linking a SIMPLE TEMPLATE<> in this use-case that I couldn't figure out how to address).
FURTHER, the "Bounty Ended", but nobody else wanted to take this on (no other answers?), so looks like "+100" goes to nobody. (heavy-sigh)
This question has a lot of answers but none of them quite capture what was happening in my codebase, and what I suspect the OP was seeing back in 2012 when this question was asked.
The Problem
The COMDAT error on an IID_* type is easy to accidentally reproduce by using the #import directive with both the rename_namespace and named_guids attributes.
If two #imported type libraries contain the same interface, as is likely the case for OP's IXMLDOMImplementation, then the generated .tlh files will declare IID_IXMLDOMImplementation in both namespaces, leading to the duplicate.
For example, the code generated for:
#import <foo.tlb> rename_namespace("FOO") named_guids;
#import <bar.tlb> rename_namespace("BAR") named_guids;
...could be simplified into something like this:
namespace FOO {
extern "C" __declspec(selectany) const GUID IID_IFOOBAR = {0};
}
namespace BAR {
extern "C" __declspec(selectany) const GUID IID_IFOOBAR = {0};
}
Here's a simple RexTester reproduction of the problem: https://rextester.com/OLAC10112
The named_guids attribute causes the IID_* to be generated and the rename_namespace attribute wraps it in the namespace.
Unfortunately, in this case, extern "C" does not seem to work as expected when it appears inside a C++ namespace. This causes the compiler to generate multiple definitions for IID_FOOBAR in the same .obj file.
DUMPBIN /SYMBOLS or a hex editor confirms the duplicate symbols.
The linker sees these multiple definitions and issues a duplicate COMDAT diagnostic.
A Solution
Knowing that rename_namespace doesn't play well with named_guids, the obvious solution is to simply not use them together. It's probably easiest to remove the named_guids attribute and instead use the _uuidof() operator.
After removing named_guids from #import directives and touching up the code, replacing all uses of FOO::IID_IFooBar with _uuidof(FOO::IFooBar), my COM-heavy codebase is back to building again.
This issue is reported as a bug in some specific versions of Visual Studio 2017. Try patching 15.9.1 or later to fix this issue
Reported Issue in VS 15.8 Preview 4
Resolved patchs in VS 15.9 Preview 2
I encountered this problem whilst porting some code (1) from MSVC to GCC. To get the build to link on GCC, I had to provide empty implementations for some specialised templated functions (2), and this resulted in LNK1179 on MSVC. I was able to resolve by inlining the functions (3), i.e.
template<> template<> void LongName1<LongName2>::FunctionName(boost::library::type1 & a, const unsigned int b);
template<> template<> void LongName1<LongName2>::FunctionName(boost::library::type1 & a, const unsigned int b) {};
template<> template<> inline void LongName1<LongName2>::FunctionName(boost::library::type1 & a, const unsigned int b) {};
I had to do
c++ -> code generation -> enable function - level linking -> no
Hopefully my lame workaround will help someone: I make sure to manually delete ALL .obj AND intermediate build files (including at least .pch, .pdb, .tlog, .lastbuildstate and anything else just hanging out looking suspicious) and rebuild from scratch.
I suggest without evidence that having some files left over from a previous build tends to cause the problem to happen more frequently. In my specific build system, I delete and recreate the .vcxproj and .sln files from scratch as well.
My own personal suspicion is that some kind of race condition exists in the build/link process between the time that intermediate files are read and the time they are written in a large project. Again, I have no evidence this is true, but this is my only guess that seems to fit all the known facts of the bug.
I wrote Outlook addins years ago and I was asked to write another. Right off the bat, I ran into this problem and through a little process of elimination, I fixed mine.
It turns out that when you choose an extensibity project(I hand coded mine back in the day), it creates and save 2 objects that I was unaware of: DTE and DTE80. To create the interfaces that manipulate these objects, they import directly from the DLLs in stdafx.h. Being that I'm working on Outlook, I also needed to import a couple of interfaces: Office and Outlook.
So, seeing as this error popped up almost immediately after writing my first tidbits of code, I started over, and added one thing at a time. The project blew chunks in the described way right after I added:
//Added mvc
//The following #import imports MSO based on it's LIBID
#import "libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52" version("2.2") lcid("0") rename_namespace("Office") raw_interfaces_only named_guids
using namespace Office;
//The following #import imports Outoloks Object lib based on it's LIBID
#import "libid:00062FFF-0000-0000-C000-000000000046" rename_namespace("Outlook") raw_interfaces_only named_guids
using namespace Outlook;
So, seeing as I had no intention of figuring out the DTE stuff, I just commented out them and anything having to do with them:
//The following #import imports VS Command Bars based on it's LIBID
// #import "libid:1CBA492E-7263-47BB-87FE-639000619B15" version("8.0") lcid("0") raw_interfaces_only named_guids
//The following #import imports DTE based on it's LIBID
// #import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("8.0") lcid("0") raw_interfaces_only named_guids
//The following #import imports DTE80 based on it's LIBID
// #import "libid:1A31287A-4D7D-413e-8E32-3B374931BD89" version("8.0") lcid("0") raw_interfaces_only named_guids
After wandering around fixing the compile errors, it compiled and linked just fine. I'm not suggesting this will work for everybody, but it worked for me. Good luck to any who pass by here....
I got this error and was really confused about it. Ended commenting out everything in the referenced cpp and reintroduce things in small batches until the file was back in the same state as when I started. And I don't get the error anymore. To me this points to this in my case being a bug in the compiler but since I can't reproduce it anymore I can't get help further than that.
I'm on:
Microsoft Visual Studio Professional 2019
Version 16.11.3
I am a fairly novice programmer who recently started using boost. After successfully linking the libraries with cmake, I have noticed that my vim (syntastic plugin I think) which does a great job at highlighting syntax errors. But ever since i started including boost libraries, it just stops at the #include statement with (no such file / directory ) and fails to show up any syntax errors whatsoever in the rest of the file. I have search all over the place but I am unable to find a workaround which allows me to syntax check bad code prior to the compilation stage. any help will be appreciated.
I am unable to post screenshots (too low rating) but will post code for whatever it is worth
#include <iostream>
#include <boost/regex.hpp> <--------------syntax error (though it compiles fine)
#include <algorithm>
using namespace std;
void testMatch(const boost::regex& ex,const string st){
cout<<"Matching" <<st <<endl;
if(boost::regex_match(ex,st)){
cout<<"matches"<<endl
}
else cout<<"oops"; }
void testSearch(const boost::regex& ex, const string st){
cout<<"Searching"<<endl;
}
If you are using the Syntastic plugin, take a look at the file in
syntastic/syntax_checkers/cpp.vim
there are lots of language specific options that can be set, I think the one you'll want is
let g:syntastic_cpp_include_dirs=['path/to/boost/files']
this lets the sytax checker know that there are other places to look for included files besides the default ones.
I'm using bison & flex (downloaded via cygwin) with vc++. When I compile the program I got an error:
...: fatal error C1083: Cannot open include file: 'unistd.h': No such file or directory
The corresponding code in the flex-generated file is:
#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.h", since it is non-ANSI. We include it way
* down here because we want the user's section 1 to have been scanned first.
* The user has a chance to override it with an option.
*/
/* %if-c-only */
#include <unistd.h>
/* %endif */
/* %if-c++-only */
/* %endif */
#endif
If I define YY_NO_UNISTD_H in the flex file(.l) this error will disappear, but I get several other errors:
...: error C2447: '{' : missing function header (old-style formal list?)
...: warning C4018: '<' : signed/unsigned mismatch
...: error C3861: 'isatty': identifier not found
How can I fix this problem?
All these errors occur in the flex-generated scanner.
I know it's because unistd.h doesn't exist in windows. Do I have to write my own unistd.h? If so how to write it in order to eliminate those errors?
isatty is used by the lexer to determine if the input stream is a terminal or a pipe/file. The lexer uses this information to change its caching behavior (the lexer reads large chunks of the input when it is not a terminal). If you know that your program will never be used in an interactive kind, you can add %option never-interactive to you lexer. When the program is run with user input, use %option interactive. When both uses are desired, you can either generate an interactive lexer, which gives a performance loss when used in batch mode, or provide your own isatty function.
Use %option nounistd in your .l file to remove the dependence on unistd.h.
just in case somebody's still this problem, Flex comes with unistd.h within its devel files. I found this here:
http://sourceforge.net/tracker/index.php?func=detail&aid=931222&group_id=23617&atid=379173
to put it short, just make sure your compiler can reach it. in my case it's just adding "C:\GnuWin32\include" to the additional inclusion directories
use win_flex.exe with option --wincompat and you dont need to hack your lex file
unistd.h is a UNIX header, so it's not present in VC++; your best bet is probably to compile it using g++ in Cygwin (or mingw/msys). You could also look at this question for other suggestions.
I'm using flex 2.5.4 that comes from the GnuWin32 project, which doesn't check for YY_NO_UNISTD_H.
In my version, Flex looks for unistd.h only when being compiled as C++, so you can save yourself all this trouble if your yylval doesn't use any C++ constructs.
I had to use the STL in yylval (using a pointer to make it a POD type), so in order to make flex compile in C++ I created this simple unistd.h:
#include <io.h>
That's all it takes (actually, I could copy the unistd.h file that comes with GnuWin32, like flyontheweb suggests).
P.S. To wrap things up: in Bison I put yylval's required STL header files in %code requires {} and added the current directory to the INCLUDE paths in my makefile.
I am too late but anyway I will share my findings to save someone still looking for answer.
In my case having an empty unistd.h file in the location where compiler looks for headers works for me.
Well this post is old but I face the same problem and here is something that should work.
WinFlexBison
I ran into this problem recently after upgrading to Angular 14.
npm install -g latest-version
resolved my issue.