How to set up OpenCV, LibTorch, and Torchvision with Cmake for Mac

4 minute read

Setting Up CMake

First, open up terminal you install homebrew with the command

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Then, use homebrew to install CMake

$ brew install cmake

Setting Up OpenCV

Just follow instructions here https://thecodinginterface.com/blog/opencv-cpp-vscode/

Setting Up LibTorch

https://pytorch.org/cppdocs/installing.html

First, download and unzip the libtorch folder from https://pytorch.org/get-started/locally. Pick the libtorch C++/Java option.

Then place the libtorch folder to wherever you want to keep it though keep in mind the file path to the libtorch folder. The CMakeLists.txt files created later will use the file path to libtorch.

Setting Up TorchVision (Updated Apr. 2022)

The following steps are based on the installation steps given from the torchvision repo “https://github.com/pytorch/vision”.

First download the repo from “https://github.com/pytorch/vision” and place it somewhere convenient where you want to keep your cmake libraries. Take note of the file path to the downloaded repo.

Use your favourite text editor to go into vision/CMakeLists.txt file and add the following line near the beginning:

list(APPEND CMAKE_PREFIX_PATH "/path/to/libtorch")	

This allows cmake to find the libtorch library. Change the path to your libtorch library. Remember to change the “/path/to/libtorch” path to wherever you’ve placed your libtorch folder downloaded in the “Setting Up LibTorch” step.

If you are using an M1 chip, the default processor (CPU) architecture is likely arm64. To check the chip architecture, use the command

$ arch

If you are using arm64 architecture, you may change it to x86_64 by adding following line to the vision/CMakeLists.txt file:

set(CMAKE_OSX_ARCHITECTURES "x86_64")

Then while still in in the vision folder that you have downloaded from the repo, make a “build” folder and change directory into it.

$ mkdir build
$ cd build

Then inside the vision/build folder, use the following commands. It could take some time to run the “make” command:

$ cmake ..
$ make
$ make install

Building An App

In this section, we create an demo app to test the success of the installation.

First create the torch-demo folder somewhere:

$ mkdir torch-demo
$ cd torch-demo

Inside the torch-demo folder, you make a main.cpp file which contains:

#include <torch/torch.h>
#include <iostream>

int main() {
  torch::Tensor tensor = torch::rand({2, 3});
  std::cout << tensor << std::endl;
}

Then, make a CMakeLists.txt file in the torch-demo folder using your favourite text editor. Remember to change the path/to parts to wherever you set up your opencv, libtorch, and torchvision folders:

# CMakeLists.txt

# Older versions of CMake are likely to work just fine but, since
# I don't know where to cut off I just use the version I'm using
cmake_minimum_required(VERSION "3.17")

# name of this example project
project(torch-demo)

#set(CMAKE_OSX_ARCHITECTURES "x86_64")
list(APPEND CMAKE_PREFIX_PATH "/path/to/libtorch")
list(APPEND CMAKE_PREFIX_PATH "/path/to/vision")


# set OpenCV_DIR variable equal to the path to the cmake
# files within the previously installed opencv program
set(OpenCV_DIR /path/to/opencv/install/lib/cmake/opencv4)

# Tell compiler to use C++ 14 features which is needed because
# Clang version is often behind in the XCode installation
set(CMAKE_CXX_STANDARD 14)

# configure the necessary common CMake environment variables
# needed to include and link the OpenCV program into this
# demo project, namely OpenCV_INCLUDE_DIRS and OpenCV_LIBS
find_package( OpenCV REQUIRED )

# tell the build to include the headers from OpenCV
include_directories( ${OpenCV_INCLUDE_DIRS} )

# specify the executable target to be built
add_executable(torch-demo main.cpp)

# tell it to link the executable target against OpenCV
target_link_libraries(torch-demo ${OpenCV_LIBS} )

# This due to LibTorch's version is the one included in the Python
# package that links to Python.
find_package(Python3 COMPONENTS Development)

# Add torchvision libraries

cmake_minimum_required(VERSION 3.10)
list(APPEND CMAKE_PREFIX_PATH "/path/to/opencv/vision")

# The first thing do is to tell cmake to find the TorchVision library.
# The package pulls in all the necessary torch libraries,
# so there is no need to also add `find_package(Torch)` here.
find_package(TorchVision REQUIRED)

target_compile_features(torch-demo PUBLIC cxx_range_for)
target_link_libraries(torch-demo TorchVision::TorchVision)
set_property(TARGET torch-demo PROPERTY CXX_STANDARD 14)

Building and Compiling Your App

Inside the torch-demo folder, create a “build” folder as follow

$ mkdir build
$ cd build

Then build the libraries inside the build folder using with the optional addition of -DWITH_CUDA=on if you need to use CUDA:

$ cmake ..
      OR
$ cmake -DWITH_CUDA=on ..

Then compile your program with either of the following commands:

$ cmake --build . --config Release
      OR
$ make

Then in the build folder, there should be a torch-demo executable which can be run as follows:

$ ./torch-demo

Possible Errors

You may encounter some of the following errors during the installation process:

library not found for -lmkl_intel_ilp64

This problem seems to involve the mkl library. I’ve found that uninstalling and reinstalling the mkl library in my Python environment helps with this problem.

#include “torchvision/vision.h” file not found

Either you forgot to create the build folder in the vision repo using the make command or the path to the vision folder in the CMakeLists.txt file in your project is incorrect. See the section on “Setting Up TorchVision”

Undefined symbols for architecture x86_64: “vision::cuda_version()”, referenced from…

This is likely because your processor (CPU) architecture is arm64 rather than x86_64. To check, use the “arch” command in terminal and if so add the line “set(CMAKE_OSX_ARCHITECTURES “x86_64”)” to both the CMakeLists.txt file in the vision folder and for your project.

I’ve had trouble making the torchvision library work with arm64, so setting it to x86_64 seems to be an answer.

Updated: