Generally for any C/C++ projects, I have to go with Linux, because most of the times the dependent code base would have something or the other, or maybe the people that I have to collaborate with, would have Linux specific dependencies. Having said that, I do miss the wonderful IntelliSense that Visual Studio comes with. Although Visual Studio Code does alleviate the itch, it’s more like a Band-Aid, than a proper cure. Add to that, with the newest iterations of Visual Studio, the ability to deploy to multiple platforms and platform specific IntelliSense, the itch got worse. Plus, the one IDE supports multiple languages now and is a very complete solution. Not to mention the support for Vim key bindings and Git integration are just icing on the cake (or cupcakes, if you fancy those).
So, as with my life, something really weird happened, I came across a C++ project, which I needed for my own project, which was only “compile-able” on Windows! (Imagine that!) It came with its own cmake, so it was just a simple setup to get it up and running (after some fiddling with the environment variables, of course). But this made me want to set up Visual Studio for my C++ development. And since the normal way of using CMake seemed too mainstream and I had too much coffee to fall asleep anyways, I decided to take it a step further. I knew Visual Studio can be configured internally with paths to look for dependencies. Since most of my work in C++ almost always has PCL and OpenCV, I decided to get rid of the CMake dependencies.
“But what about when using the project on someone else’s computer?” I hear you say. If the other person is using windows, then it is just adding a simple file to the project. As for Linux folks, I am looking into a workaround for the portability, which might come up in another post (Just need to make sure it works).
So no matter what your project is, you can just drop in the file and Intellisense picks up everything. No need to fiddle with CMake and all.
Also, OpenCV and PCL doesn’t really have good install instruction on Windows (from my experience), so this also serves as that. But the steps should work with any other libraries that you might need add support for. So let’s get started!
The official PCL website currently only has version 1.6, when the latest (as of the date of writing this article) is version 1.8. I really don’t know why PCL does this. But thanks to 杉浦 司 (Tsukasa Sugiura), you can get prebuilt PCL 1.8 libraries for both Visual Studio 2015 and 2013. The binaries are All-In-One, that is, it includes all the PCL files along with any other 3rd parties required. So grab the one that fancies you from here.
Unlike PCL, OpenCV does keep the Windows binaries updated and it is as simple as going to the official website and grabbing the windows version. And please grab the latest one (3.2 at the time of this article).
Although the PCL package was supposed to get all the third party packages, I found that it doesn’t installs freeGLUT. FreeGLUT binaries for windows are a bit tough to get hold on. So grab them from here. Get the one for Visual Studio (MSVS)
Once you have those, simply install them one by one. Make a note of where they are installed, you’ll need to come back to that later. PCL’s installer is pretty good that it asks to add the environment variables for you. I HIGHLY RECOMMEND YOU ALLOW IT.
Next, go to System Properties Dialogue for Windows → Environment Variables (an easy way to do it is to just press the windows button and then type Environment variable and select “Edit the system environment variables”)
Once there, look up and see if you have the Environment Variable called “PCL_ROOT” and “OPENNI2_LIB64” (depending on whether you installed OpenNI2 and which architecture you opted for). Also note that the variables might be under the System variables section OR under the User variables section, depending on what choice you made during the installation. It shouldn’t matter where, user variables keeps you from accidentally messing up the entire system.
In case the variables are not there, create them, along with the following additional ones, and point them as follows:
- PCL_ROOT → The install path you chose to install PCL. It should have folders like 3rdParty under Eg: G:\Program Files\PCL 1.8.0
- OPENNI2_LIB64 → The Lib folder under the place where your OpenNI2 is installed. Eg: G:\Program Files\OpenNI2\Lib
- OPENNI2_INCLUDE64 → The Include folder under the place where your OpenNI2 is installed. Eg: G:\Program Files\OpenNI2\Include
- OPENNI2_REDIST64 → The Redist folder under the place where your OpenNI2 is installed. Eg: G:\Program Files\OpenNI2\Redist
- OPENCV_DIR → Go to your opencv install/unpack directory. Navigate to build → x64 (or 32 if you opted for 32 bits) → vc14 (in case you are using VS 2013, this should be vc12. But I highly recommend upgrading to 2015). Set the value of the environment value to this folder. To check if you are in the correct place, the folders bin and lib should be UNDER the pointed folder. Eg: E:\OpenCVWin10\opencv\build\x64\vc14
- FREEGLUT_DIR → Set this to the location where you installed/extracted freeGLUT. Directories like bin and include should be UNDER the pointed folder. Eg: E:\FreeGlut
Once these are done, click Apply and OK till you close all the dialog boxes. I like to perform a sanity check at this point with Environment variables to see if the changes have been propagated to the system and I set them to folders that actually exists. For this, press win + R, to bring up the run box and enter the environment variables surrounded by % signs (eg: %PCL_ROOT%). Press enter. If the proper folders open up, then those are set properly. If not, then go back to them and set them up properly. Do this for all the environment variables and you are across the most confusing part!
Making Visual Studio see the libraries:
Still here? Good! Now fire up Visual Studio and start a new Console application project. Make sure to disable the SDL checks and enable the precompiled headers. The former makes VS throw up errors because of certain deprecated functions within PCL (a workaround is to comment the lines if you want to keep the SDL features. I don’t really need them, so I keep them turned off). The latter is recommended as this improves the build times a lot because chances are that you will be using common PCL headers in projects and PCL can be painfully slow while compiling the headers. So apart from the initial compilation time, this should boost up the subsequent build times substantially.
Bring up the Property Manager window (View→Other Windows→Property Manager).
Expand the tree and choose the architecture that you will be working with. Let’s assume 64 bit, and we will work with the Debug config.
So right-click on “Debug | x64” subtree and select “Add new project property sheet…”
Give it a good name, save it and remember the location where you saved it. Better still, create a backup of it and you won’t have to go through reading this (maybe boring) Blog post when the Computer gods smite you down in anger.
Once done you should see the property sheet showing up under the tree. Double click it (or right-click properties) to bring up the Property Pages.
Expand and go to C/C++ → General
Click Edit under Additional Include Directories
Double click on the white box and add the following:
$(OPENCV_DIR)\..\..\include $(PCL_ROOT)\include\pcl-1.8\ $(PCL_ROOT)\3rdParty\VTK\include\vtk-7.0 $(PCL_ROOT)\3rdParty\Boost\include\boost-1_61 $(PCL_ROOT)\3rdParty\Qhull\include $(PCL_ROOT)\3rdParty\FLANN\include $(PCL_ROOT)\3rdParty\Eigen\eigen3 $(OPENNI2_INCLUDE64) $(FREEGLUT_DIR)\include
Visual studio automatically infers the absolute path from the environment variables. So if you need to setup on another machine, all you need to do is to set up the environment path and add this property sheet to the project and visual studio will do the rest. No need to maintain the exact directory structure as your original setup.
Next, go to Linker → General
Click Edit under Additional Include Directories
Double click on the white box and add the following (these are the library location):
$(OPENCV_DIR)\lib $(PCL_ROOT)\lib $(PCL_ROOT)\3rdParty\VTK\lib $(PCL_ROOT)\3rdParty\Boost\lib $(PCL_ROOT)\3rdParty\Qhull\lib $(PCL_ROOT)\3rdParty\FLANN\lib $(OPENNI2_LIB64) $(FREEGLUT_DIR)\lib\x64
Next, go to Linker → Input
Click Edit under Additional Dependencies
Open up a command prompt. For each of the library locations set up above do the following:
Navigate to the library location in the command prompt. Enter “dir *.lib /B > store.txt”, without the quotes Copy the contents of the store.txt file that was created in the same location and add it to the Additional Dependencies section in the Visual Studio Property windows.
This method will list all the library files (anything ending with .lib) and store them in the text file called store, instead of outputting it to the console window. This needs to be done for all the listed libraries. Some of the libraries might be like “opencv_world320.lib” & “opencv_world320d.lib”. Notice the d at the end of the second one? That shows that it is a debug library and it should be used when the build config is setup to Debug. So if you want to separate based on the config, you have to remove the names of the debug libraries, for the Release config and vice versa. But it depends on your requirements. I generally work with Release configs, so my configs are with release libraries in them.
Once that is done, click OK and you’re done!
Test out if VS picks up the libraries by typing a include and see if IntelliSense suggests opencv/pcl etc. Note: Sometimes IntelliSense might need a moment to parse through the directories. In which case you will notice it show up in the status bar on the bottom. Once it shows Ready on the bottom left, it should be all ready to go. Another common problem, often, is to have the wrong build config set. VS will only show the relevant libraries for the currently selected config. So if you added it to Debug | x64 only and set your config to Debug | x86, VS the libraries won’t show up on IntelliSense.
You can now just share the property sheet that you created over other environments and as long as the other environment has the prerequisites installed and the environment variables set up, visual studio will pick it up without any problems. Plus, you can create such configurations for different libraries and add multiple property sheets to the same/different build configurations. So now you have a system that gets ready for your libraries with just one click. Nifty!