CMake find specific package of multiple packages with different versions (NCurses) - c++

I currently have a CMake file that finds and links a library (NCurses) to another library
...
set(CURSES_NEED_NCURSES TRUE)
find_package(Curses REQUIRED)
include_directories(${CURSES_INCLUDE_DIR})
add_library(myLibrary STATIC ${sources})
target_link_libraries(myLibrary ${CURSES_LIBRARIES})
target_compile_options(myLibrary PUBLIC -std=c++20 -Wall -Wconversion)
...
This works fine, however unfortunately it is pulling up a different version than I need (5.7 instead of 6.1)
#include <ncurses.h>
#include <iostream>
int main()
{
std::cout << "VERSION: " << NCURSES_VERSION;
}
outputs: VERSION: 5.7
I do have the desired package installed under: /usr/local/ncurses/6_1.
But the logs seem to say it is pulling it from a different location: Found Curses: /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/lib/libncurses.tbd
How can I specify which of these I want to use?

Okay I have figured this out, to anyone else who might come across this.
First I installed the latest version of ncurses (6.3) from here: https://invisible-island.net/ncurses/#downloads-h2
(I downloaded the gzipped tar)
I then went through and deleted all references in my usr/local i could find to ncurses.
I then extracted the tar, and entered the new directory.
I ran just plain ./configure inside the directory (with no flags).
After that finished, I ran make
Then I ran make install, after removing symlinks to stop collisions, make install was able to run properly.
Ensure that the CMake variable CURSES_NEED_NCURSES is set to TRUE before finding the package:
set(CURSES_NEED_NCURSES TRUE)
find_package(Curses REQUIRED)
and it will work perfectly :)

Related

Installing package via vcpkg causing a "opencv2/opencv.hpp: No such file or directory" error

I have installed vcpkg and opencv using vcpkg to try import the opencv library in c++ and I keep getting the following error:
main.cpp:2:10: fatal error: opencv2/opencv.hpp: No such file or directory
2 | #include <opencv2/opencv.hpp>
This is my simple main.cpp:
#include <iostream>
#include <opencv2/opencv.hpp> //I have also tried using "" instead
using namespace cv; //I have tried not using this line
int main(int, char**) {
std::cout << "Hello, world!\n";
}
I have tested to see whether this was a problem with opencv, but when I installed and tried importing the booster library via vcpkg, the same issue persists.
I have a windows 10, and I am currently using VScode as my main editor, although I don't think it's a VScode problem because it doesn't matter whether use the run package in atom, vscode, or windows terminal, cygwin, or powershell the same error pops up.
I have tried many things including uninstalling and reinstalling vcpkg, adding the library, and bin files to the path in system environment variables, reinstalling everything in my C: drive instead of my D: drive, using cmake and even changing the #include statement to the following variations:
#include <opencv2>
#include <opencv>
However, I noted when I used the following import statement instead:
#include <C:\Users\nick-\DEV\opencv\build\include\opencv2\opencv.hpp>
I got this error:
C:\Users\nick-\DEV\opencv\build\include\opencv2\opencv.hpp:48:10: fatal error: opencv2/opencv_modules.hpp: No such file or directory
48 | #include "opencv2/opencv_modules.hpp"
Which originated in one of the files of the opencv library.
I'm using vcpkg because I had previously tried using cmake and the issue wasn't resolved, the other StackOverflow link is [here][1] in case it's somewhat helpful. (I tried what was suggested and I found and moved the opencv library to the right address and it didn't help)
EDIT: Minimal reproducible example as per #Alan Birtles's suggestion,
These are the steps that I did:
Install vcpkg by git cloning the [vcpkg repo][2]
Run the bootstrap command (.\vcpkg\bootstrap-vcpkg.bat)
installed opencv via vcpkg (vcpkg install opencv)
integrate vcpkg packages globally (vcpkg integrate install)
Created a main file (main.cpp) which you see above, I have made slight edits to it to make it minimal.
Then I compiled main.cpp (g++ main.cpp -o main) and got the error
Then I tried the above troubleshooting steps (as well as tons of others I can't remember) and remained with the issue at hand.
EDIT: Attempted reincorporating cmake
Following #Genjutsu's suggestion in the comment, I have done the following steps to re-setup cmake and get it working (it hasn't worked)
Installed the cmake, cmake tools, and cmake integration extensions on vscode
Run "cmake configure" as an executable
Added a handful of lines to my CMakeLists.txt file which I have shown below
cmake_minimum_required(VERSION 3.0.0)
project(fpc VERSION 0.1.0)
include(CTest)
enable_testing()
set(CMAKE_TOOLCHAIN_FILE "C:/Users/nick-/DEV/vcpkg/scripts/buildsystems/vcpkg.cmake")
set(CMAKE_PREFIX_PATH "C:/Users/nick-/DEV/vcpkg/installed/x64-windows")
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(fpc main.cpp)
target_link_libraries(fpc ${OpenCV_LIBS})
message("OpenCV_INCLUDE_DIRS: " ${OpenCV_INCLUDE_DIRS})
message("OpenCV_LIBS: " ${OpenCV_LIBS})
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
Which give me the following output:
[main] Configuring folder: floorplan pathfinder cpp
[cmake] Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19043.
[cmake] OpenCV_INCLUDE_DIRS: C:/Users/nick-/DEV/opencv/build/include
[cmake] OpenCV_LIBS: opencv_calib3dopencv_coreopencv_dnnopencv_features2dopencv_flannopencv_gapiopencv_highguiopencv_imgcodecsopencv_imgprocopencv_mlopencv_objdetectopencv_photoopencv_stitchingopencv_videoopencv_videoioopencv_world
[cmake] Configuring done
[cmake] Generating done
And finally I performed the suggested actions to use vcpkg with cmake under "Visual Studio Code with CMake Tools", and set my workplace's settings.json to this:
{
"cmake.configureSettings": {
"CMAKE_TOOLCHAIN_FILE": "D:/Program Files/vcpkg/scripts/buildsystems/vcpkg.cmake"
}
}
EDIT: Added a manifest file (and also edited the cmake file)
So I added a vcpkg.json manifest file to the best of my abilities, which is shown below. And modified my CMakeLists.txt file with changes reflected above.
{
"name": "example",
"version-string": "0.0.1",
"dependencies": [
"OpenCV"
]
}
Simply said:
a) VS Code is not affect by vcpkg integrate install, only MSBuild is ...
b) setting the CMAKE_TOOLCHAIN_FILE only works before the very first project() call
c) setting CMAKE_TOOLCHAIN_FILE before project() via cmake.configureSettings or other means does not work if there is already a configured cmake cache.
d) don't modify CMAKE_PREFIX_PATH
So starting from a clean cmake build without any cache: Set CMAKE_TOOLCHAIN_FILE before project() by any means you want and it works. You might also need to set VCPKG_TARGET_TRIPLET.
(using #include <opencv2/opencv.hpp> seems fine)

Compiling and Running CGAL Triangulation Demo

I am trying to use the CGAL library to display a 2D Delaunay triangulation, like in the example here
My code looks like this:
#include <iostream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/draw_triangulation_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_2<K> Triangulation;
typedef Triangulation::Point Point;
int main(void){
Point a(1,1), b(2,1), c(2,2), d(1,2);
Triangulation T;
T.insert(a);
T.insert(b);
T.insert(c);
T.insert(d);
CGAL::draw(T);
return 0;
}
When I try to compile this code with g++ -o cgalTest.exe cgalTest.cpp -lCGAL -lgmp the program compiles successfully, but on runtime I get Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined
By searching on Google, I found someone that suggested using g++ -o cgalTest.exe cgalTest.cpp -lCGAL -lgmp -DCGAL_USE_BASIC_VIEWER which produces the following error on compile time: /usr/include/CGAL/Qt/Basic_viewer_qt.h:30:10: fatal error: QApplication: No such file or directory #include <QApplication>
I am using ubuntu 19.04, so I installed CGAl using sudo apt-get install libcgal-dev and sudo apt-get install libcgal-qt5-dev
I tried to install sudo apt-get install libqt5svg5-dev libqt5opengl5-dev as well to solve the error, but to no avail.
Do I need to install additional libraries? Maybe the compilation must be done differently?
Thank you
Ok, for anyone facing the same problem, here is how I solved it:
First, I used the locate QApplication command to find the location of the QApplication header file on my system. Be sure to run sudo updatedb before using locate. If locate doesn't find the location of QApplication then you are missing qt libraries. Try sudo apt-get install qt5-default and the other libraries I mentioned in my question, run sudo updatedb and try locate QApplication again.
When you find the path to QApplication just use the -I option to instruct the compiler to use it. Here is an example g++ -o delaunayTest delaunayTest.cpp -lCGAL -lgmp -lCGAL_Qt5 -DCGAL_USE_BASIC_VIEWER -I/usr/include/x86_64-linux-gnu/qt5/QtWidgets/ (because in my case, QApplication was inside the directory /usr/include/x86_64-linux-gnu/qt5/QtWidgets/)
Trying to compile with this, you will probably get another header file error. Repeat the same process using locate until you get no more header file errors.
At that point, you will likely encounter an undefined reference to symbol error.
To solve this, use locate again to find the location of the file that caused the error (for example libQt5OpenGL.so.5) and add the path to the compilation command as is (for example g++ -o delaunayTest delaunayTest.cpp /usr/lib/x86_64-linux-gnu/libQt5OpenGL.so.5) along with all the previous options.
You will probably get several undefined reference to symbol errors as well. Just keep using the same method until you don't get any.
At this point the program should compile properly and run properly.
Note that if you have multiple versions of qt installed, then the above might not work properly (If for example you have software that uses qt like MATLAB or anaconda installed in your system. You will know because locate will produce many paths for each file on the steps above). In such a case, I suggest building a Virtual Machine, downloading the CGAL libraries and qt5-default and following the above steps there, since it is very likely this won't work in a system with multiple qt installations.
Another option (maybe the easiest), using CMake, is to generate the file using the builtin script:
From the source file directory, run cgal_create_CMakeLists -c Qt5
Edit the generated CMakeLists.txt adding the line add_definitions(-DCGAL_USE_BASIC_VIEWER)
My generated and edited CMakeLists.txt:
# Created by the script cgal_create_CMakeLists
# This is the CMake script for compiling a set of CGAL applications.
cmake_minimum_required(VERSION 3.1...3.15)
project( tmp_cgal )
# CGAL and its components
find_package( CGAL QUIET COMPONENTS Qt5 )
if ( NOT CGAL_FOUND )
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
endif()
add_definitions(-DCGAL_USE_BASIC_VIEWER) # <==== I've added this
# Boost and its components
find_package( Boost REQUIRED )
if ( NOT Boost_FOUND )
message(STATUS "This project requires the Boost library, and will not be compiled.")
return()
endif()
# include for local directory
# include for local package
# Creating entries for all C++ files with "main" routine
# ##########################################################
create_single_source_cgal_program( "b.cpp" )
Create a build directory: mkdir build
Change directory: cd build
Generate the build files: cmake ..
Build: make
Run the binary file. For me it's ./b because my source file was b.cpp
Environment:
These instructions should work for an Ubuntu 20.04.1 (or similar) with the packages libcgal-dev, libcgal-qt5-dev and qtbase5-dev installed (and, of course, cmake, make and g++).
Main references:
doc1 and doc2

Adding Boost to CMake project?

Background
I'm a complete newb with C++ and I've been running into one headache after another, so forgive me if this is incredibly simple and I'm just that dumb...
I have a project that should ultimately compile and run in Linux. Unfortunately after lots of issues with my C++ development environemnt (still unresolved), I gave up on trying to develop in Linux and moved to Windows Visual Studio 2017. My hope was to get my code working in Windows and then, since C++ is supposedly a portable language, it should just work in Linux with minimal changes.
For a day or so Visual Studio seemed to be working. I could write code, hit "compile", and like magic it would run. I threw together a few classes to construct a directed acyclic graph, used the standard library for a hash table, and then I tried to create a socket...
Windows and Linux use different libraries for sockets (<sys/socket.h> vs <winsock.h>) so I needed some way to abstract the differences, and I preferred a well-established standard. Googling around I found the Boost library that seemed to fit my needs... That's when everything went to hell.
My project setup
Because this project will be developed across a variety of platforms and IDEs (some people use Windows + Visual Studio, some people use Mac + Eclipse, and others use Linux + VIM) I opted to make it a CMake project. After several hours of reading and learning and research it seems like CMake should give me what I want (convenient and reproducible cross-platform builds with little or no dependency issues)
My source code (directly from the Boost Getting Started on Windows guide) is as follows:
CMakeProject2.cpp
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
using namespace boost::lambda;
typedef std::istream_iterator<int> in;
std::for_each(
in(std::cin), in(), std::cout << (_1 * 3) << " ");
}
Per the Boost Getting Started on Windows guide, I downloaded Boost from here:
https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.zip
(interestingly, the Getting Started guide is titled "Boost Getting Started on Windows - 1.69.0", yet it linked to Boost versions 1.67.0)
After downloading and extracting the ZIP file, I had a whole mess of files - but no idea where to put them:
Attempts to Get It Working So Far
I tried to add the Boost library to my project, but none of the expected menu options were available:
Although I couldn't find a single page that warns you of this gotcha, apparently CMake projects don't have the elusive "Properties" window - and instead third party libraries must somehow be included via the CMakeLists.txt file
For starters, I copied the entire 540 MB contents of the Boost ZIP file to within my project under the folder name "Boost":
I then tried a series of different CMakeList.txt commands:
Per How do you add Boost libraries in CMakeLists.txt?:
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED COMPONENTS lambda)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(CMakeProject2 "CMakeProject2.cpp" "CMakeProject2.h")
target_link_libraries(CMakeProject2 ${Boost_LIBRARIES})
endif()
Per https://www.selectiveintellect.net/blog/2016/7/29/using-cmake-to-add-third-party-libraries-to-your-project-1:
include("Boost")
add_subdirectory("Boost")
add_subdirectory("boost")
add_subdirectory("Boost/boost")
add_subdirectory("Boost/boost/lambda")
target_link_libraries(boost)
target_link_libraries(Boost)
Per https://cmake.org/pipermail/cmake/2009-November/033249.html:
SET (Boost_FIND_REQUIRED TRUE)
SET (Boost_FIND_QUIETLY TRUE)
SET (Boost_DEBUG FALSE)
set (Boost_USE_MULTITHREADED TRUE)
set (Boost_USE_STATIC_LIBS TRUE)
SET (Boost_ADDITIONAL_VERSIONS "1.67" "1.67.0")
FIND_PACKAGE(Boost COMPONENTS lambda)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
I tried several other incantations (not being familiar with C++ or CMake as a tool) and either received errors from CMakeLists.txt, or from CMakeProject2.cpp about cannot open source file "boost/lambda/lambda.hpp". In fact, with regards to those "CMakeLists.txt" errors, after adding enough lines to my file I started to crash Visual Studio regularly. Note that I have an 8th generation i7, 32 gigabytes of RAM, and an M.2 NVMe hard drive -- so I was rather impressed that a few lines in a text file pissed off Microsoft enough to lock up my computer for 10 minutes at a time.
Failing all of that, I tried copying the files I needed directly into my project:
Now, again, I'm new to C/C++ development and everything that can go wrong has gone wrong. So far I've spent almost two weeks and barely managed to compile a single "Hello, World" app across two computers, three IDEs, and four compilers. I've yet to have any success including a third party library, from anywhere, of any popularity level or simplicity level, and actually compile a functioning program that references the library. So believe me when I say: I don't know the difference between a "header-only library" and... whatever the alternative is. I just know that, according to the Boost Getting Started on Windows guide, most of Boost is "headers only" and therefore I shouldn't have any build step -- it should be simple to use it. Furthermore, this example (using boost::lambda) is - per their instructions - a header-only library, and should therefore be extremely easy to use.
I now updated the source code slightly to look in the current directory, instead of looking in the system include directory (which, as far as I'm aware at this point, doesn't exist in Windows):
#include "boost/lambda/lambda.hpp"
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
using namespace boost::lambda;
typedef std::istream_iterator<int> in;
std::for_each(
in(std::cin), in(), std::cout << (_1 * 3) << " ");
}
Now I can manually verify that this file exists (the file CMakeProject2\CMakeProject2\boost\lambda\lambda.hpp can be found in File Explorer) - yet I'm still getting errors:
cannot open source file "boost/lambda/lambda.hpp"
Some further Googling led me to update my CMakeLists.txt file once more, putting it in its current form:
# CMakeList.txt : CMake project for CMakeProject2, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.8)
# Add source to this project's executable.
file(GLOB CMakeProject2_SRC
"*.h"
"*.cpp"
"**/*.h"
"**/*.cpp"
"**/*.hpp"
"boost/lambda/lambda.hpp"
)
add_executable (CMakeProject2 ${CMakeProject2_SRC})
#add_executable (CMakeProject2 "CMakeProject2.cpp" "CMakeProject2.h")
# TODO: Add tests and install targets if needed.
Despite this I'm still getting the error:
cannot open source file "boost/lambda/lambda.hpp"
At this point I'm ripping my hair out. What am I doing wrong? What do I not know? How is something as simple as the Boost-equivalent of "Hello, World" not working for me?
Following recipe should work
Download Boost binaries from official boost binaries location and install to say C:\Boost
Most times you do not need to build Boost on your own.
Your CMakeLists.txt should look like follows
cmake_minimum_required (VERSION 3.8)
project(boostAndCMake)
set(BOOST_ROOT "C:\Boost") # either set it here or from the command line
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED COMPONENTS system) # header only libraries must not be added here
add_executable(CMakeProject2 CMakeProject2.cpp CMakeProject2.h)
target_include_directories(CMakeProject2 PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(CMakeProject2 ${Boost_LIBRARIES})
Because we used REQUIRED on the find_package call, CMake will fail execution and skip the rest of the script if it cannot be found. So no need to check Boost_FOUND. You need to check it, when you omit REQUIRED.
Now from the command line call from the directory where your script resides:
cmake -H. -Bbuildit -G "Visual Studio 15 2017" -DBOOST_ROOT=C:\Boost
This creates a build directory named buildit in the current directory, further creates a solution for Visual Studio 2017 inside the build directory and provides the setting for the variable BOOST_ROOT that is used in the find_package call to identify the Boost directory on your computer. To see what options are available on the find_package(Boost ...) call see FindBoost documentation in CMake.
Header Only Libraries
If your libraries are header only you need to omit them from the find_package(Boost ...) call. To see which libraries are not header only see this post.
Using newer Boost versions
If your CMake installation cannot find the requested version, e.g. 1.69.0, but supports the naming scheme of the more recent Boost version you can use it with set(Boost_ADDITIONAL_VERSIONS "1.69.0" "1.69"). Last change of the Boost naming scheme was from 1.65.1 to 1.66.
Here's a working setup for Boost 1.68 with CMake 3.12. Boost 1.69 is apparently "too new" for cmake to detect it properly. Since boost is not buildable by cmake, cmake itself must provide a FindBoost.cmake module that must keep up with boost changes.
So anyway, the CMakeLists.txt is as small as this:
cmake_minimum_required(VERSION 3.11)
project(foobar)
find_package(Boost 1.68 REQUIRED)
add_executable(foo foo.cpp)
target_link_libraries(foo PUBLIC Boost::boost)
Of course, you can split it in many subdirectories.
Invoking CMake in the command line should look like this:
cmake -DCMAKE_PREFIX_PATH=path_to_local_directory ..
Where path_to_local_directory is the installation path of all library you want to depend on. It will work for Boost, nlohmann_json, glfw3, Qt, you name it *(1). For my case, it was C:/local/ and another case was ../external/ (yes, it can be a directory local to the project!)
Let's take a peek at my own C:/local/:
ls -l /c/local/
total 12
drwxr-xr-x 1 myself 197609 0 May 26 2018 boost_1_67_0/
drwxr-xr-x 1 myself 197609 0 Sep 5 02:02 boost_1_68_0/
WARNING: Ensure your compiler architecture is the same as the installed boost version. Or else cmake will simply not find it.
I think that about it. The next CMake version (3.14) should work with the latest boost.
*(1) The said library will either need to export it's CMake target or you must provide a FindXXX.cmake
I'm using CMake 3.22 with Boost version 1.78.
The simplest solution is to set the Boost_INCLUDE_DIR when calling Cmake:
cmake -DBoost_INCLUDE_DIR=boost
Pass the directory to where the Boost libraries are. If you're using Visual Studio you can also set this in your CMake Settings:
Or, in the CMakeSettings.json file:
"cmakeCommandArgs": "-DBoost_INCLUDE_DIR=boost",
In my opinion, this is better than using the set function because you're not hard coding the path.
Add a target_include_directories(CMakeProject2 PRIVATE .) into your CMakeList.txt.
The . is the relative path of boost/lambda/lambda.hpp from CMakeLists.txt
And you should not add any .hpp file to the source list.

Building Open Source library Teem with Levmar support using CMake

I try to build the library Teem under Windows 64bit with levmar support using cmakeGUI with generator VisualStudio10 Win64.
First off all, i built Levmar with CLAPACK and F2C. That works fine as levmar can be compiled without errors and the demo succeds.
The mysterious thing is, when i try to build teem with levmar support ON, cmake always turns it off "because it was not found" although i told cmake the path to levmar.lib.
Thats what the CmakeGUI tells me:
"warning: Turning off Teem_LEVMAR, because it wasn't found.
Configuring done"
Here is a part of my CMakeList.txt delivered with teem:
# Look for "levmar" library <http://www.ics.forth.gr/~lourakis/levmar/>
option(Teem_LEVMAR "Build Teem with levmar library support." OFF)
set(Teem_LEVMAR_LIB "")
if(Teem_LEVMAR)
find_package(LEVMAR)
if(LEVMAR_FOUND)
add_definitions(-DTEEM_LEVMAR)
set(Teem_LEVMAR_LIB ${LEVMAR_LIBRARIES})
set(Teem_LEVMAR_IPATH ${LEVMAR_INCLUDE_DIR})
else()
# We need to set this as a cache variable, so that it will show up as
# being turned off in the cache.
message("warning: Turning off Teem_LEVMAR, because it wasn't found.")
set(Teem_LEVMAR OFF CACHE BOOL "Build Teem with levmar library support." FORCE)
endif()
endif()
Has anyone an idea what happens here?
I tried the same thing with 3 different levmar.lib and different generators but unfortunately i suggest that i have to tell cmake the exact name of the library or the name levmar.lib is simply wrong.
I reported that question also to my supervisor for my thesis but he had the same problem and could not help me.
I also tried to modify the CMakeList:
#if(Teem_LEVMAR)
include_directories(${LEVMAR}/lib)
#endif()
which was originally
if(Teem_LEVMAR)
include_directories(${Teem_LEVMAR_IPATH})
endif()
but it did not help.
Why does cmake recognizes levmar.lib not as the levmar library, in fact does not accept it.
i also tried to understand why find_package(levmar) does not succeed but now i do not know any ways to make it work.
greetings,
jan luca.

How to tell CMake to use during compilation specific version of Qt?

There are two versions of Qt installed on my Ubuntu - 5.2 (default) and 5.4 (in /opt/Qt/5.4/gcc_64):
CMakeLists.txt:
project(testproject)
find_package(Qt5Core HINTS /opt/Qt/5.4/gcc_64 REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main Qt5::Core)
main.cpp:
#include <QDebug>
int main()
{
qDebug() << "runtime version: " << qVersion() << " compiled with: " << QT_VERSION_STR << endl;
return 0;
}
Running the program:
cmake . && make clean && make && LD_LIBRARY_PATH=/opt/Qt/5.4/gcc_64/lib ./main
Output:
runtime version: 5.4.0 compiled with: 5.2.1
How to tell inside CMake to use Qt 5.4 instead of default Qt 5.2? I've tried several options for HINTS in find_package but none of them looks to work.
I took a look through the CMake files generated by an installation of Qt5, and no where in those files are hints being ingested from the caller. These CMake files all use relative paths once one of them is picked up.
That is, if you're looking for the core library, then all of the dependencies that version of the core library will be the correct version. So the goal is to get it to pick the right CMake module when you call find_package, and there are a couple of ways to do that using CMake level hints.
Export CMAKE_PREFIX_PATH
You can set the prefix path to the base directory your Qt is installed to. The base directory is the directory containing lib/ and bin/. In your case, this might be something like this:
export CMAKE_PREFIX_PATH=/opt/Qt/5.4/gcc_64:$CMAKE_PREFIX_PATH
and then from the same shell session run your cmake commands.
Set Qt5Core_DIR in your CMakeLists.txt
This requires setting a variable that points to the right CMake root module you want your Qt to be found from:
set(Qt5Core_DIR /opt/Qt/5.4/gcc_64/lib/cmake/Qt5Core)
find_package(Qt5Core REQUIRED)
Of course, the issue with this is that if you wanted to find another module, you'd have to set the specific Qt5<MODULE>_DIR variable before your find_package call.