Setting VIPS library for visual studio 2012 - visual-studio-2012

I am trying libvips for visual studio 2012, starting with a simple example at
http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/vipsmanual/vipsmanualse1.html#x6-60001.1.1
#include <iostream>
#include <vips/vips>
int
main (int argc, char ⋆⋆argv)
{
if (argc != 3)
{
std::cerr << "usage: " << argv[0] << " infile outfile\n";
return (1);
}
try
{
vips::VImage fred (argv[1]);
fred.invert ().write (argv[2]);
}
catch (vips::VError e)
{
e.perror (argv[0]);
}
return (0);
}
What I did was:
Download and extract libvips at http://www.vips.ecs.soton.ac.uk/supported/7.34/win32/
Add to VC++ Directories->Include directories as vips-dev-7.34.1\include (vips-dev-7.34.1 is the extracted folder)
Add to VC++ Directories->Library directories as vips-dev-7.34.1\lib
Add a system path entry as vips-dev-7.34.1\bin
Basically because there are not much guide on using libvips with visual studio, so I applied the procedure that I used for OpenCV. The guide only say "All you need to do is include . This will get all of the include you need". Aparrently there are much more than that.
Upon building, the first error is "Unable to find header file "glib-object.h". Essentially, vips/vips call glib-objects "include which lies inside a subfolder of include \include\glib-2.0\glib-objects.h. I searched for a way to make VS search for all subfolders within the main include folder, it seems that such "recursive search" is not possible in VS. One has to point exactly to the folder containing header file and I may need to add all of the subfolders manually. So I tried adding vips-dev-7.34.1\include\glib-2.0 to VC++ Directories->Include directories. But then glib-objects.h calls for another glibconfig.h which is nowhere to be found within the include folder and subfolders.
Have someone sucessfully make libvips work with VS? Can you give me some advices if I miss something.

I'm the libvips maintainer. Sorry, it's very difficult to use the pre-built libvips binaries with VS, for various reasons (see below). I think your options are to use mingw instead, to cross-compile from linux (this is what I do), or to rebuild libvips yourself from source using VS (perhaps a week's work for an experienced dev?). There are some notes on the vips website about this issue.
The libvips.dll on the website has been cross-compiled from linux using mingw. It's set up for a linux-style build system with pkg-config, so you will have a lot of compiler flags to figure out in VS, and it's built against msvcrt.dll, the Windows C runtime, rather than msvcrtXX.dll, the VS runtime, so you will have endless annoying compatibility problems unless you also build against the Windows runtime.
Unfortunately VS no longer supports building against the Windows runtime. They have an internal tool which does support this mode, but it's not publicly available. I read somewhere you can coax the DDK compiler into doing this, but it's also not supported.
CoApp is an interesting project (partly supported by Microsoft) that is attempting to make building software on Windows less painful, but it's still in beta. You could maybe ask if they have a libvips packaged up for VS, or are considering making one.

Related

Rcpp with structured library in /src

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).

Boost thread library version mismatch

I've created a managed C++ log parser application using C++ vectors and Winforms. I want to add multithreading and Boost seemed like a better option than Winforms BackgroundWorker because I want to be able to execute my existing C++ function with each thread. I installed Boost multiple times following multiple different tutorials (lastly this one: https://levelup.gitconnected.com/the-definite-guide-on-compiling-and-linking-boost-c-libraries-for-visual-studio-projects-c79464d7282d) and I still have the same issue when I try to #include <boost/thread.hpp>
Error LNK1104 cannot open file 'libboost_thread-vc143-mt-x64-1_78.lib'
I don't know why it's looking for this library when I have Boost 1_79 installed not 1_78. My .lib file also has "mt-gd-x64" not just "mt-x64". I've already specified the correct file path to the library in Project->Properties->Linker->General->Additional Library Directories. I've also tried installing Boost via Visual Studio 2022 NuGet Package Manager. The lib file in that folder is also slightly off. "vc120" instead of "vc143". I've even tried changing the .lib file name to match the file name in the linker error exactly but when I do that I get more errors like LNK1104 cannot open file 'libboost_chrono-vc143-mt-x64-1_78.lib'
Do I just need to delete all my Boost files and download version 1_78 and try again? Why is Visual Studio looking for the wrong file name when it compiles? Is my #include statement wrong?
I ended up solving this problem by downloading boost 1_78, building it, and specifying that folder instead or the 1_79 folder. If anyone might know why the program was looking for 1_78 instead of 1_79 feel free to respond Also big thanks to George Gkasdrogkas who wrote the tutorial that worked best for me on how to install Boost. Tutorial is linked in the question :)

How to build OpenImageIO 1.4.12 with VS2015

I am trying to build dependencies for a project, currently based on VS2013, with VS2015.
Most of them are building without problems, either as they are or with some patch, but I am totally at a loss with OpenImageIO 1.4.12.
I am passing parameters to cmake and msbuild that set up use of VS2015 for everything, and indeed the generated solution files indicate "vc140_xp" as the chosen toolset.
But at link time I receive error like this one, indicating that somewhere there is a reference to boost libraries built with VS2013:
LINK : fatal error LNK1104: cannot open file 'libboost_thread-vc120-mt-1_56.lib' [F:\...\deps\x64\oiio-Release-1.4.12\build\src\libOpenImageIO\OpenImageIO.vcxproj]
Of course I have a bunch of libboost_xxx-vc140-mt-1_56.lib in another place, since I've built them also with VS2015. Also dependencies set up in solution file correctly refer to libboost_xxx-vc140-mt-1_56.lib files and to the correct path, and by doing a FINDSTR in all OpenImageIO build tree I'm not able to find any reference to the older VS version.
But the same command lists a lot of .obj files containing those references, such as (put on multiple lines for better readability):
build\src\libOpenImageIO\OpenImageIO.dir\Release\xmp.obj:/FAILIFMISMATCH:"_CRT_STDIO_ISO_WIDE_SPECIFIERS=0"
libboost_regex-vc120-mt-1_56.lib
libboost_thread-vc120-mt-1_56.lib
libboost_date_time-vc120-mt-1_56.lib
libboost_system-vc120-mt-1_56.lib
libboost_chrono-vc120-mt-1_56.lib
Is it because of these references that link fails looking for different versions of boost libs? Where can these references come from? And how can I get rid of them, since apparently they are nowhere to be found in my configuration?
This problem is in boost itself, not in OpenImageIO, and is caused by the used version of boost being released before VS2015.
As pointed out by kenba in his comment, this answer points to the solution:
Visual Studio 2013 (vs120) asks for wrong boost libraries.
The full explanation, related to an older version of boost and VS, can be found here:
How do I specify, which version of boost library to link to?.
In the case of VS2015, here is how the corresponding lines of code in boost/config/auto_link.hpp should appear:
# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800)
// vc11:
# define BOOST_LIB_TOOLSET "vc110"
# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1900)
// vc12:
# define BOOST_LIB_TOOLSET "vc120"
# elif defined(BOOST_MSVC)
// vc14:
# define BOOST_LIB_TOOLSET "vc140"
Implementing these lines solved my problem.

How to fix Visual Studio linker frustration

I am pretty experienced writing my own code, but not in C++. I am used to adding .NET assembly references, and I want to get into using C++.
I downloaded a VC++ 6 project presenting a graph algorithm, opened it in Visual Studio 2010 Ultimate and downloaded the required libraries (LEDA .NET assemblies) however, they came with both DLLs and LIB so I thought I would have no problems with the .NET and C++ connection. Also, the LEDA project comes with C++ style .header files, and static libraries, yet frustration persists.
I put my LEDA header files in a directory visible to the project, since I can "Go to definition" of all the custom LEDA data types and see where they are defined in the LEDA include files.
But, I can not compile/link these data types in. The VS finds their very existence repulsive, and refuses to acknowledge they could possibly be found in leda.lib.
Steps I have already taken:
Added additional /LIBPATH path under Properties ->Linker->General
Added explicit lib references under Properties->Linker->Input
Added all the paths containing LEDA header files and libraries to every path location I can find, like include path, reference path, library path.
Copied the DLLs and LIBs to the release folder as well as the base folder of the project.
Added a #pragma comment( lib, "leda" )
Still no joy.
It's quite bad since none of the custom typedefs are recognised the errors balloon to 646 errors.
If anyone is kind enough to offer assistance, thank you.
I can't guarantee this will work but try the following steps (therefore using it's default predefined paths instead of setting your own ones) :
1) Copy *.dll into Windows/System32 or / and (there is some confusion about x64 and x32 default checking in my head :)) Windows/SysWOW64.
2) Copy *.h files into x:\PathToVC2010\include\
3) Copy *.lib files into x:\PathToVC2010\lib\

fatal error C1084: Cannot read type library file: 'Smegui.tlb': Error loading type library/DLL

I am trying to build an old version of an application which consists of VC++ projects that were written in Visual Studio 2003.
My OS is Windows 7 Enterprise (64-bit).
When I try and build the solution I get the following errors:
error C4772: #import referenced a type from a missing type library; '__missing_type__' used as a placeholder
fatal error C1084: Cannot read type library file: 'Smegui.tlb': Error loading type library/DLL.
They both complain about the following import statement:
#import "Smegui.tlb" no_implementation
This is not a case of the file path being incorrect as renaming the Smegui.tlb file causes the compiler to throw another error saying it cannot find the library.
Smegui is from another application that this one depends on. I thought perhaps I was missing a dll but there is no such thing as Smegui.dll.
All I know about .tlb files is that they are a type library and you can create them from an assembly using tlbexp.exe or regasm.exe (the later also registers the assembly with COM)
There is also an Apache Ant build script which uses a custom task to invoke devenv.com to build the projects. This is the same script that the build server originally used to build the application. It gives me the same errors when I try and run it.
The strangest thing about this is that I knew it ought to work seeing as it is all freshly checked out from subversion. I tried many different combinations of admin vs user elevation, VS vs Ant build, cleaning, release.
I have got it to build successfully about 5 times but the build seems to be non-deterministic.
If anyone can shed some light on how this tlb stuff even works or what this error might mean I would greatly appreciate it.
I found a far more reliable solution: open the tlb with oleview.exe and then close it.
Not sure what this actually does but it works every time.
I think oleview is actually one of the samples included with Visual Studio but I haven't had the time to debug it and see what it is doing.
I ran into this error because one type library was trying to load a dependent type library, which it could not find. Even though the dependent type library was in the same directory, and even though that directory was in the searchable path, the compiler would error loading the first type library, but not mention the dependent type library in the error.
To find the pseudo-missing type library, I ran Process Monitor (procman64.exe) during the compile. This showed that after the reported type library had successfully loaded, a dependent type library could not be found. It even showed all of the places that it was looking for the dependent type library, none of which were where it should have been looking (e.g.: ).
The fix was to add a <PreBuildEvent> to the project to copy the dependent .tlb file to one of the directories that was actually being searched.
<PreBuildEvent>
<Command>copy /Y ..\Lib\Interop\CWSpeechRecLib.tlb .\</Command>
</PreBuildEvent>
http://msdn.microsoft.com/en-us/library/sce74ah7%28VS.71%29.aspx
smegui.tlb is referencing some other tlb that the compiler can't find. If you have the .idl for smegui you might be able to figure out what the other is. I suspect the missing tlb is something that original build machine had registered but that your machine doesn't have registered.
A type library is a binary description of a set of interfaces, coclasses and enums. They're usually generated for COM components, in the case of tlbexp and regasm the tlb is created from the assembly metadata. For native COM components they are usually generated from an idl (Interface Description Language) file by the midl tool.
Edit:
I just noticed you're on x64 Windows. Are you building the project with a new version of Visual Studio? If so, are you targeting x86 or x64? If the latter, it may simply be a 32bit component that the compiler can't find (or less likely, a x64 component the x86 compiler can't find if you are targeting x86), for WOW64 the registry is virtualized for x86 vs. x64 applications.
Well I finally found out why I managed to get it to build sometimes and not others... sort of.
So long as I ran the build script with elevated administrator permissions and let that get as far as it could until that error occurred, then run the build script again as a protected administrator succeeded. Those steps must be done in that exact order with no other steps in between. If I try build in Visual Studio it does not work (although I did get it to succeed once). Probably some kind of virtualisation issue although it still doesn't quite make sense.
Well I don't need help on this any more and I know it's probably impossible to fully answer this question without knowing exactly what the build is doing. However if anyone does have any more thoughts I would happily receive them.
Cheers,
Steiny

Resources