Using CMake to compile Assimp on Windows 10 - cmake

I am attempting to use assimp for model importing in openGL. However, when building assimp 4.1.0, I get this:
15>-- Install configuration: "Debug"
15>CMake Error at cmake_install.cmake:36 (file):
15> file cannot create directory: C:/Program Files
15> (x86)/Assimp/lib/cmake/assimp-4.1. Maybe need administrative privileges.
I should have administrative privileges, but I am not entirely sure. If not, how would I update this. If this is not the case, what would another course of action be? My project and assimp both are under Debug as well as Win32 (this gave a prior error, so I changed that).
Thank you.

I'm trying another way which #Daniel Schepler said, install other places and then set the PATH to the prefix path in environment:
Example on my cmake and build and install: [in Window10]
# cmake
cmake -DCMAKE_INSTALL_PREFIX=D:\Users\installpkg\bin -S . -B build -G "MinGW Makefiles"
# build and install
cmake --build build --target install
Explain a little bit:
-DCMAKE_INSTALL_PREFIX=D:\Users\installpkg\bin This flag is set the install path to = path
-G "MinGW Makefiles" is for MinGW to make.
Then you will see the result [Like I'm installing the glog now]:
PS D:\Users\installpkg\glog> cmake --build build --target install
Consolidate compiler generated dependencies of target glogbase
[ 30%] Built target glogbase
[ 34%] Built target glog
[ 38%] Built target glogtest
Consolidate compiler generated dependencies of target logging_unittest
[ 46%] Built target logging_unittest
Consolidate compiler generated dependencies of target logging_custom_prefix_unittest
[ 53%] Built target logging_custom_prefix_unittest
Consolidate compiler generated dependencies of target stl_logging_unittest
[ 61%] Built target stl_logging_unittest
Consolidate compiler generated dependencies of target demangle_unittest
[ 69%] Built target demangle_unittest
Consolidate compiler generated dependencies of target utilities_unittest
[ 76%] Built target utilities_unittest
Consolidate compiler generated dependencies of target cleanup_immediately_unittest
[ 84%] Built target cleanup_immediately_unittest
Consolidate compiler generated dependencies of target cleanup_with_absolute_prefix_unittest
[ 92%] Built target cleanup_with_absolute_prefix_unittest
Consolidate compiler generated dependencies of target cleanup_with_relative_prefix_unittest
[100%] Built target cleanup_with_relative_prefix_unittest
Install the project...
-- Install configuration: ""
-- Installing: D:/Users/installpkg/bin/lib/libglog.dll.a
-- Installing: D:/Users/installpkg/bin/bin/libglog.dll
-- Installing: D:/Users/installpkg/bin/include/glog/export.h
-- Installing: D:/Users/installpkg/bin/include/glog/logging.h
-- Installing: D:/Users/installpkg/bin/include/glog/raw_logging.h
-- Installing: D:/Users/installpkg/bin/include/glog/stl_logging.h
-- Installing: D:/Users/installpkg/bin/include/glog/vlog_is_on.h
-- Installing: D:/Users/installpkg/bin/include/glog/log_severity.h
-- Installing: D:/Users/installpkg/bin/include/glog/platform.h
-- Installing: D:/Users/installpkg/bin/lib/pkgconfig/libglog.pc
-- Installing: D:/Users/installpkg/bin/lib/cmake/glog/glog-modules.cmake
-- Installing: D:/Users/installpkg/bin/lib/cmake/glog/glog-config.cmake
-- Installing: D:/Users/installpkg/bin/lib/cmake/glog/glog-config-version.cmake
-- Installing: D:/Users/installpkg/bin/lib/cmake/glog/glog-targets.cmake
-- Installing: D:/Users/installpkg/bin/lib/cmake/glog/glog-targets-noconfig.cmake

Related

Couldn't find LibSSH on msys2 even the libssh-devel has installed with pacman

I'm trying to compile the libnetconf2 with msys2 environment on Windows 10 OS. But I get a wired(I guess) issue about libssh.
I have installed libssh libssh2 libssh-devel libssh2-devel and the pkg-config also find the location of libssh:
$ pkg-config --list-all
autoopts AutoOpts - A semi-automated generated/library option parser
form formw - ncurses 6.2 add-on library
formw formw - ncurses 6.2 add-on library
libalpm libalpm - Arch Linux package management library
libcrypto OpenSSL-libcrypto - OpenSSL cryptography library
libmagic libmagic - Magic number recognition library
libpcre libpcre - PCRE - Perl compatible regular expressions C library with 8 bit character support
libpcre16 libpcre16 - PCRE - Perl compatible regular expressions C library with 16 bit character support
libpcre2-16 libpcre2-16 - PCRE2 - Perl compatible regular expressions C library (2nd API) with 16 bit character support
libpcre2-32 libpcre2-32 - PCRE2 - Perl compatible regular expressions C library (2nd API) with 32 bit character support
libpcre2-8 libpcre2-8 - PCRE2 - Perl compatible regular expressions C library (2nd API) with 8 bit character support
libpcre2-posix libpcre2-posix - Posix compatible interface to libpcre2-8
libpcre32 libpcre32 - PCRE - Perl compatible regular expressions C library with 32 bit character support
libpcrecpp libpcrecpp - PCRECPP - C++ wrapper for PCRE
libpcreposix libpcreposix - PCREPosix - Posix compatible interface to libpcre
libpkgconf libpkgconf - a library for accessing and manipulating development framework configuration
libssh libssh - The SSH Library
libssh2 libssh2 - Library for SSH-based communication
libssl OpenSSL-libssl - Secure Sockets Layer and cryptography libraries
$ pkg-config --modversion libssh
0.9.6
And then run the command "cmake .." in
libnetconf2/build
, which gives the error:
$ cmake ..
CMake Warning at CMakeLists.txt:171 (message):
valgrind executable not found! Disabling memory leaks tests.
-- Could NOT find CMocka (missing: CMOCKA_LIBRARIES CMOCKA_INCLUDE_DIR) (Required is at least version "1.0.1")
-- Disabling tests because of missing CMocka
-- Could NOT find Uncrustify (missing: UNCRUSTIFY) (Required is at least version "0.71")
-- OpenSSL found, required for TLS
CMake Error at /usr/share/cmake-3.21.3/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find LibSSH (missing: LIBSSH_LIBRARIES) (Required is at least
version "0.7.1")
Call Stack (most recent call first):
/usr/share/cmake-3.21.3/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
CMakeModules/FindLibSSH.cmake:113 (find_package_handle_standard_args)
CMakeLists.txt:239 (find_package)
-- Configuring incomplete, errors occurred!
And then I try to compile libssh from source code, after compiling and installation, the cmake still can't find the correct libssh (Below is the log for libssh compile and install):
$ make install
Consolidate compiler generated dependencies of target ssh
[ 58%] Built target ssh
Consolidate compiler generated dependencies of target libssh_scp
[ 63%] Built target libssh_scp
Consolidate compiler generated dependencies of target sshnetcat
[ 68%] Built target sshnetcat
Consolidate compiler generated dependencies of target ssh-client
[ 73%] Built target ssh-client
Consolidate compiler generated dependencies of target scp_download
[ 78%] Built target scp_download
[ 80%] Built target libsshpp
Consolidate compiler generated dependencies of target samplesshd-cb
[ 82%] Built target samplesshd-cb
Consolidate compiler generated dependencies of target senddata
[ 87%] Built target senddata
Consolidate compiler generated dependencies of target exec
[ 92%] Built target exec
Consolidate compiler generated dependencies of target libsshpp_noexcept
[ 94%] Built target libsshpp_noexcept
Consolidate compiler generated dependencies of target keygen
[ 96%] Built target keygen
Consolidate compiler generated dependencies of target samplesftp
[100%] Built target samplesftp
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/pkgconfig/libssh.pc
-- Installing: /usr/local/lib/cmake/libssh/libssh-config-version.cmake
-- Installing: /usr/local/include/libssh/callbacks.h
-- Installing: /usr/local/include/libssh/libssh.h
-- Installing: /usr/local/include/libssh/ssh2.h
-- Installing: /usr/local/include/libssh/legacy.h
-- Installing: /usr/local/include/libssh/libsshpp.hpp
-- Installing: /usr/local/include/libssh/sftp.h
-- Installing: /usr/local/include/libssh/server.h
-- Installing: /usr/local/include/libssh/libssh_version.h
-- Installing: /usr/local/lib/libssh.dll.a
-- Installing: /usr/local/bin/msys-ssh-4.dll
-- Installing: /usr/local/lib/cmake/libssh/libssh-config.cmake
-- Installing: /usr/local/lib/cmake/libssh/libssh-config-noconfig.cmake
BTW, the LD_LIBRARY_PATH has added:
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
I have resolved this issue as the link:
Libgit2 and libssh2 CMake package 'libssh2' not found
/usr/local is the prefix path that I compiled and installed the libssh from source code.
cmake -DLIBSSH_INCLUDE_DIRS=/usr/local/include/libssh -DLIBSSH_LIBRARIES=/usr/local/lib/ ..

undefined symbols remain, but shared libraries compile and seem to function properly

My goal was to build shared libraries from SUNDIALS 2.7.0 - these are solvers of ordinary differential equations, written in C.
I've downloaded the source, and followed the installation guide:
run Cmake (with GUI), checked options "CVODE" (this is one of the available solvers - the only one I wanted), "build shared libraries" and "use generic (std-c) math libraries" and generated the Makefile.
run make && make install in the Linux console and my shared libraries got generated, with no error messages at all.
Here is the output:
$ make
Scanning dependencies of target sundials_nvecserial_shared
[ 3%] Building C object src/nvec_ser/CMakeFiles/sundials_nvecserial_shared.dir/nvector_serial.c.o
[ 7%] Building C object src/nvec_ser/CMakeFiles/sundials_nvecserial_shared.dir/__/sundials/sundials_math.c.o
[ 11%] Linking C shared library libsundials_nvecserial.so
[ 11%] Built target sundials_nvecserial_shared
Scanning dependencies of target sundials_cvode_shared
[ 14%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode.c.o
[ 18%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_io.c.o
[ 22%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_direct.c.o
[ 25%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_band.c.o
[ 29%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_dense.c.o
[ 33%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_diag.c.o
[ 37%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_spils.c.o
[ 40%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_spbcgs.c.o
[ 44%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_spgmr.c.o
[ 48%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_sptfqmr.c.o
[ 51%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_sparse.c.o
[ 55%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_bandpre.c.o
[ 59%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/cvode_bbdpre.c.o
[ 62%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_nvector.c.o
[ 66%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_math.c.o
[ 70%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_direct.c.o
[ 74%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_band.c.o
[ 77%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_dense.c.o
[ 81%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_iterative.c.o
[ 85%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_sparse.c.o
[ 88%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_spbcgs.c.o
[ 92%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_spgmr.c.o
[ 96%] Building C object src/cvode/CMakeFiles/sundials_cvode_shared.dir/__/sundials/sundials_sptfqmr.c.o
[100%] Linking C shared library libsundials_cvode.so
[100%] Built target sundials_cvode_shared
$ sudo make install
[ 11%] Built target sundials_nvecserial_shared
[100%] Built target sundials_cvode_shared
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/include/sundials/sundials_config.h
Install shared components
-- Installing: /usr/local/include/sundials/sundials_band.h
-- Installing: /usr/local/include/sundials/sundials_dense.h
-- Installing: /usr/local/include/sundials/sundials_direct.h
-- Installing: /usr/local/include/sundials/sundials_iterative.h
-- Installing: /usr/local/include/sundials/sundials_math.h
-- Installing: /usr/local/include/sundials/sundials_nvector.h
-- Installing: /usr/local/include/sundials/sundials_fnvector.h
-- Installing: /usr/local/include/sundials/sundials_pcg.h
-- Installing: /usr/local/include/sundials/sundials_sparse.h
-- Installing: /usr/local/include/sundials/sundials_spbcgs.h
-- Installing: /usr/local/include/sundials/sundials_spfgmr.h
-- Installing: /usr/local/include/sundials/sundials_spgmr.h
-- Installing: /usr/local/include/sundials/sundials_sptfqmr.h
-- Installing: /usr/local/include/sundials/sundials_types.h
Install NVECTOR_SERIAL
-- Installing: /usr/local/lib/libsundials_nvecserial.so.2.7.0
-- Installing: /usr/local/lib/libsundials_nvecserial.so.2
-- Installing: /usr/local/lib/libsundials_nvecserial.so
-- Installing: /usr/local/include/nvector/nvector_serial.h
Install CVODE
-- Installing: /usr/local/lib/libsundials_cvode.so.2.9.0
-- Installing: /usr/local/lib/libsundials_cvode.so.2
-- Installing: /usr/local/lib/libsundials_cvode.so
-- Installing: /usr/local/include/cvode/cvode_band.h
-- Installing: /usr/local/include/cvode/cvode_bandpre.h
-- Installing: /usr/local/include/cvode/cvode_bbdpre.h
-- Installing: /usr/local/include/cvode/cvode_dense.h
-- Installing: /usr/local/include/cvode/cvode_diag.h
-- Installing: /usr/local/include/cvode/cvode_direct.h
-- Installing: /usr/local/include/cvode/cvode.h
-- Installing: /usr/local/include/cvode/cvode_sparse.h
-- Installing: /usr/local/include/cvode/cvode_spbcgs.h
-- Installing: /usr/local/include/cvode/cvode_spgmr.h
-- Installing: /usr/local/include/cvode/cvode_spils.h
-- Installing: /usr/local/include/cvode/cvode_sptfqmr.h
-- Installing: /usr/local/include/cvode/cvode_impl.h
These shared libraries seem to function properly in my Project, for which I needed them - ordinary differential equations are getting solved and the output seems to be identical to other solvers that are independent of these.
But there is one big but :):
Checking for undefined symbols in the generated shared libraries show me the short list of standard functions - here are the outputs for the shared libraries:
$ nm -D --undefined-only libsundials_cvode.so.2.9.0
w __cxa_finalize
U exp
U fprintf
U fputc
U free
U fwrite
w __gmon_start__
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U malloc
U memset
U pow
U printf
U putchar
U realloc
U sqrt
U __stack_chk_fail
U stderr
U vsprintf
and
$ nm -D --undefined-only libsundials_nvecserial.so.2.7.0
w __cxa_finalize
U exp
U free
w __gmon_start__
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U malloc
U pow
U printf
U putchar
U sqrt
Printing shared library dependencies gives:
$ ldd -r libsundials_nvecserial.so
linux-vdso.so.1 (0x00007ffd657a5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fecd8155000)
/lib64/ld-linux-x86-64.so.2 (0x00007fecd874c000)
undefined symbol: exp (./libsundials_nvecserial.so)
undefined symbol: pow (./libsundials_nvecserial.so)
undefined symbol: sqrt (./libsundials_nvecserial.so)
and
$ ldd -r libsundials_cvode.so linux-vdso.so.1 (0x00007ffe6a1ff000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6cd55ac000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6cd5bc8000)
undefined symbol: exp (./libsundials_cvode.so)
undefined symbol: pow (./libsundials_cvode.so)
undefined symbol: sqrt (./libsundials_cvode.so)
There are, for instance, functions like SUNRsqrt that are defined over sqrt and are very important in actual numerical calculations - this fact as well as the presence of undefined symbols makes me confused and concerned about the reliability of the shared libraries.
Before generating the shared libraries, I've set all the appropriate paths to the environmental variable LD_LIBRARY_PATH (which, by the way, was empty before):
$ export LD_LIBRARY_PATH="/usr/lib:/usr/lib/x86_64-linux-gnu:/usr/lib/gcc/x86_64-linux-gnu"
$ echo $LD_LIBRARY_PATH
/usr/lib:/usr/lib/x86_64-linux-gnu:/usr/lib/gcc/x86_64-linux-gnu
For instance, the C standard library libc.so and the C math library libm.so are stored at /usr/lib/x86_64-linux-gnu, whereas the GNU Transactional Memory Library libitim.so is stored at /usr/lib/gcc/x86_64-linux-gnu (although the version 1.0.0 of it is also at /usr/lib/x86_64-linux-gnu).
Versions of OS, Cmake, GNU C compiler and GNU Make:
$ lsb_release -d
Description: Ubuntu 18.04.5 LTS
$ cmake --version
cmake version 3.18.2
$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
$ make --version
GNU Make 4.1
Any comment would be greatly appreciated.
P.S.
This case is completely reproducible, since it is all about generating shared libraries from the SUNDIALS 2.7.0 source (direct download link) and checking them on undefined symbols.
You have undefined symbol with ldd because the so files were created without the -lm option. However it will not be a problem as long as the final executable is linked with -lm option. It is what is done for tests like test_nvector_serial which is linked with -lm -lrt.
You can see all this by running the make in a verbose mode with make VERBOSE=1.
If you try to generate the executable without -lm you will have collect2: error: ld returned 1 exit status and the linker complaining about exp, pow and sqrt.
if you add -lm when creating the so files ( I did it ). you will see :
ldd -r ./src/nvec_ser/libsundials_nvecserial.so
linux-vdso.so.1 (0x00007ffe1a769000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe4a5c19000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe4a5828000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe4a61bd000)
And in this case you can link your tests ( only to do some test for yourself if you want) without -lm.
To compile your so files with -lm. You can do it by running the command line with -lm option after entering the right folder (just for test purpose). The other way is by modifying the CMakeLists.txt which generate the so files. For libsundials_nvecserial.so for example, you modify sundials-2.7.0/src/nvec_ser/CMakeLists.txt by adding target_link_libraries(sundials_nvecserial_shared -lm) after the ADD_LIBRARY(sundials_nvecserial_shared SHARED ${nvecserial_SOURCES} ${shared_SOURCES}).
For the LD_LIBRARY_PATH, it does not have to contain something necessarily if you are looking in standard places. The linker use also /etc/ld.so.cache and search also in default path unless you use -z nodeflib. you can find more details in https://man7.org/linux/man-pages/man8/ld.so.8.html
For the nm -D. It is normal , try to compile a hello world gcc -o exec hello.c you will see that printf is undefined. Take a look at dynamic linking, and also to the -rdynamic option used to build the so files.

How to create a Yocto recipe for cmake with separate -dev package of header files?

I am trying to write a Yocto recipe for an in-house library that uses cmake to build and install itself. Running make install from the command line, the library installs the following files (headers are somewhat abridged):
-- Installing: /prefix/lib/libreflection.so
-- Installing: /prefix/lib/libreflection.a
-- Installing: /prefix/include/reflect
-- Installing: /prefix/include/reflect/type.h
-- Installing: /prefix/include/reflect/detail
-- Installing: /prefix/include/reflect/detail/type.h
-- Installing: /prefix/include/reflect/detail/property.h
-- Installing: /prefix/include/reflect/detail/iterator
-- Installing: /prefix/include/reflect/detail/iterator/range.h
-- Installing: /prefix/include/reflect/detail/accessor.h
-- Installing: /prefix/include/reflect/property.h
-- Installing: /prefix/include/reflect/register.h
-- Installing: /prefix/include/reflect/object.h
-- Installing: /prefix/lib/cmake/libreflection/libreflection-config.cmake
-- Installing: /prefix/lib/cmake/libreflection/libreflection-config-noconfig.cmake
I would like to differentiate between a binary ".so only" Yocto package (libreflection) and a development version that additionally includes the static library, header and cmake package files (libreflection-dev).
My initial recipe is as follows, but with it both libreflection and libreflection-dev package all files:
DESCRIPTION = "C++ reflection library"
SECTION = "libs"
LICENSE = "CLOSED"
SRCREV = "${AUTOREV}"
SRCBRANCH = "master"
SRC_URI = "git://gitlab.company.com/group/${PN}.git;branch=${SRCBRANCH};protocol=ssh"
inherit cmake
S = "${WORKDIR}/git"
FILES_${PN}-dev += "${libdir}/cmake"
# The following are needed because the library is unversioned.
# See https://wiki.yoctoproject.org/wiki/TipsAndTricks/Packaging_Prebuilt_Libraries#Non-versioned_Libraries
SOLIBS = ".so"
FILES_SOLIBSDEV = ""
I have tried various changes to the FILES_${PN}* variables, but none have achieved the desired effect. Generally I either end up with packaging errors, or both libreflection and libreflection-dev include all files.
How can I adjust the recipe such that libreflection includes only the .so, and libreflection-dev includes all the files?

Cmake is unable to find packages of Gmock

I am new to Cmake and Gtest. I have a problem with in CMake
find_package(GMock REQUIRED)
and
target_link_libraries(runtest ${GMOCK_BOTH_LIBRARIES} pthread).
When I build the project, CMake is unable find the GMock packages.
But when I mentioned the absolute paths of library, it is working fine.
For example:
set(GMOCK_INCLUDE_DIRS /usr/local/include/gmock)
set(GMOCK_BOTH_LIBRARIES /usr/local/lib/libgmock.a /usr/local/lib/libgmock_main.a /usr/local/lib/libgtest.a /usr/local/lib/libgtest_main.a)
Now the problem is my Supervisor recommended me to find the solution to run the code using find packages only. After doing some research, I came to know that FindGMock.cmake file is missing from the Cmake modules. I added it and run code again with find_package(), but still it is not working.
Errors are undefined references to functionalities of Gmock and Gtest.
For instance :
undefined reference to `testing::Message::Message()'.
undefined reference to testing::internal::GetBoolAssertionFailureMessage.
undefined reference totesting::internal::AssertHelper::~AssertHelper()'
Like this there too many errors.
Could anyone please explain me, how to make CMake to find the GMock packages automatically?
Here's a step-by-step example of building and linking to GMock from a CMake project on Linux from scratch. Steps 0-4 cover building and installing GMock while steps 5 and beyond address the question.
These steps are fairly generic and will work with little modification for any project that provides its own CMake package.
Step 0: Create a working directory
From my home folder, I created a blank directory called test:
alex:~$ mkdir test
alex:~$ cd test
alex:~/test$ ls
Step 1: Download GMock
GMock is included in the Google Test repository, so we clone that repository.
alex:~/test$ git clone https://github.com/google/googletest
Cloning into 'googletest'...
remote: Enumerating objects: 24427, done.
remote: Counting objects: 100% (92/92), done.
remote: Compressing objects: 100% (45/45), done.
remote: Total 24427 (delta 44), reused 72 (delta 38), pack-reused 24335
Receiving objects: 100% (24427/24427), 10.32 MiB | 2.68 MiB/s, done.
Resolving deltas: 100% (18062/18062), done.
Step 2: Configure GMock
We'll use the following command to build the googletest repository; GMock is included by default.
$ cmake -S googletest/ -B _build/googletest -DCMAKE_BUILD_TYPE=RelWithDebInfo
The -S flag sets the source directory to the root of the Google Test repository we just cloned. This tells CMake which project it's building. The -B flag sets the binary directory to ~/test/_build/googletest, which is where CMake will store intermediate build outputs before they are installed. This should always be distinct from the source directory. Finally, since we are using a single-configuration generator (Make is the default on Linux), we must specify the build type at this time. I have chosen RelWithDebInfo to keep debugging easy, but also to enable optimizations.
In general, you should always build your project with in the same configuration as its dependencies, so we'll use RelWithDebInfo again later.
For more detail on how to configure generic CMake projects, I'll refer you to this question/answer: How do I build a CMake project?
Finally, here's the output of running the command:
alex:~/test$ cmake -S googletest/ -B _build/googletest -DCMAKE_BUILD_TYPE=RelWithDebInfo
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Python: /usr/bin/python3.10 (found version "3.10.4") found components: Interpreter
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/_build/googletest
Step 3: Build GMock
Now we'll go ahead and run the build. The following command will work with any single-config generator:
alex:~/test$ cmake --build _build/googletest/
[ 12%] Building CXX object googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
[ 25%] Linking CXX static library ../lib/libgtest.a
[ 25%] Built target gtest
[ 37%] Building CXX object googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.o
[ 50%] Linking CXX static library ../lib/libgmock.a
[ 50%] Built target gmock
[ 62%] Building CXX object googlemock/CMakeFiles/gmock_main.dir/src/gmock_main.cc.o
[ 75%] Linking CXX static library ../lib/libgmock_main.a
[ 75%] Built target gmock_main
[ 87%] Building CXX object googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
[100%] Linking CXX static library ../lib/libgtest_main.a
[100%] Built target gtest_main
The build should complete relatively quickly.
Step 4: Installing GMock
At this point, you could run sudo cmake --install _build/googletest/ to install it globally to /usr/local, but I wouldn't recommend this. It's much better to keep a frequently updated dependency like Google Test/GMock tied to the project that's using it.
Instead, we will install it to a project-local prefix, like so:
alex:~/test$ cmake --install _build/googletest/ --prefix _local
-- Install configuration: "RelWithDebInfo"
-- Installing: /home/alex/test/_local/include
-- Installing: /home/alex/test/_local/include/gmock
-- Installing: /home/alex/test/_local/include/gmock/gmock-matchers.h
-- Installing: /home/alex/test/_local/include/gmock/gmock-function-mocker.h
-- Installing: /home/alex/test/_local/include/gmock/internal
-- Installing: /home/alex/test/_local/include/gmock/internal/gmock-pp.h
-- Installing: /home/alex/test/_local/include/gmock/internal/gmock-internal-utils.h
-- Installing: /home/alex/test/_local/include/gmock/internal/gmock-port.h
-- Installing: /home/alex/test/_local/include/gmock/internal/custom
-- Installing: /home/alex/test/_local/include/gmock/internal/custom/gmock-port.h
-- Installing: /home/alex/test/_local/include/gmock/internal/custom/gmock-matchers.h
-- Installing: /home/alex/test/_local/include/gmock/internal/custom/gmock-generated-actions.h
-- Installing: /home/alex/test/_local/include/gmock/internal/custom/README.md
-- Installing: /home/alex/test/_local/include/gmock/gmock-more-actions.h
-- Installing: /home/alex/test/_local/include/gmock/gmock-more-matchers.h
-- Installing: /home/alex/test/_local/include/gmock/gmock-nice-strict.h
-- Installing: /home/alex/test/_local/include/gmock/gmock.h
-- Installing: /home/alex/test/_local/include/gmock/gmock-cardinalities.h
-- Installing: /home/alex/test/_local/include/gmock/gmock-spec-builders.h
-- Installing: /home/alex/test/_local/include/gmock/gmock-actions.h
-- Installing: /home/alex/test/_local/lib/libgmock.a
-- Installing: /home/alex/test/_local/lib/libgmock_main.a
-- Installing: /home/alex/test/_local/lib/pkgconfig/gmock.pc
-- Installing: /home/alex/test/_local/lib/pkgconfig/gmock_main.pc
-- Installing: /home/alex/test/_local/lib/cmake/GTest/GTestTargets.cmake
-- Installing: /home/alex/test/_local/lib/cmake/GTest/GTestTargets-relwithdebinfo.cmake
-- Installing: /home/alex/test/_local/lib/cmake/GTest/GTestConfigVersion.cmake
-- Installing: /home/alex/test/_local/lib/cmake/GTest/GTestConfig.cmake
-- Up-to-date: /home/alex/test/_local/include
-- Installing: /home/alex/test/_local/include/gtest
-- Installing: /home/alex/test/_local/include/gtest/gtest-param-test.h
-- Installing: /home/alex/test/_local/include/gtest/internal
-- Installing: /home/alex/test/_local/include/gtest/internal/gtest-port-arch.h
-- Installing: /home/alex/test/_local/include/gtest/internal/gtest-string.h
-- Installing: /home/alex/test/_local/include/gtest/internal/gtest-death-test-internal.h
-- Installing: /home/alex/test/_local/include/gtest/internal/gtest-type-util.h
-- Installing: /home/alex/test/_local/include/gtest/internal/gtest-port.h
-- Installing: /home/alex/test/_local/include/gtest/internal/gtest-internal.h
-- Installing: /home/alex/test/_local/include/gtest/internal/gtest-param-util.h
-- Installing: /home/alex/test/_local/include/gtest/internal/gtest-filepath.h
-- Installing: /home/alex/test/_local/include/gtest/internal/custom
-- Installing: /home/alex/test/_local/include/gtest/internal/custom/README.md
-- Installing: /home/alex/test/_local/include/gtest/internal/custom/gtest.h
-- Installing: /home/alex/test/_local/include/gtest/internal/custom/gtest-port.h
-- Installing: /home/alex/test/_local/include/gtest/internal/custom/gtest-printers.h
-- Installing: /home/alex/test/_local/include/gtest/gtest-matchers.h
-- Installing: /home/alex/test/_local/include/gtest/gtest-death-test.h
-- Installing: /home/alex/test/_local/include/gtest/gtest-spi.h
-- Installing: /home/alex/test/_local/include/gtest/gtest.h
-- Installing: /home/alex/test/_local/include/gtest/gtest-test-part.h
-- Installing: /home/alex/test/_local/include/gtest/gtest-typed-test.h
-- Installing: /home/alex/test/_local/include/gtest/gtest_prod.h
-- Installing: /home/alex/test/_local/include/gtest/gtest-assertion-result.h
-- Installing: /home/alex/test/_local/include/gtest/gtest_pred_impl.h
-- Installing: /home/alex/test/_local/include/gtest/gtest-message.h
-- Installing: /home/alex/test/_local/include/gtest/gtest-printers.h
-- Installing: /home/alex/test/_local/lib/libgtest.a
-- Installing: /home/alex/test/_local/lib/libgtest_main.a
-- Installing: /home/alex/test/_local/lib/pkgconfig/gtest.pc
-- Installing: /home/alex/test/_local/lib/pkgconfig/gtest_main.pc
The --prefix flag tells cmake --install into which directory to install the project. Here, we've chosen a directory named _local in our working directory. The name of this folder is arbitrary. I've chosen this name to mirror the /usr/local prefix naming and to play nicely with a common .gitignore strategy of ignoring top-level directories prefixed with and underscore.
Notice in the command output what's getting installed. Headers, the GTest and GMock static libraries, yes, but also pkg-config files and, most importantly, the CMake package files:
-- Installing: /home/alex/test/_local/lib/cmake/GTest/GTestTargets.cmake
-- Installing: /home/alex/test/_local/lib/cmake/GTest/GTestTargets-relwithdebinfo.cmake
-- Installing: /home/alex/test/_local/lib/cmake/GTest/GTestConfigVersion.cmake
-- Installing: /home/alex/test/_local/lib/cmake/GTest/GTestConfig.cmake
These are the files that find_package will use (soon) to load GTest into a dependent project. The two standard files are GTestConfig.cmake and GTestConfigVersion.cmake. The first one is the most important, and it's responsible for actually implementing the CMake package. It will ultimately load GTestTargets.cmake and GTestTargets-relwithdebinfo.cmake, which are specific to GTest. Notice also how RelWithDebInfo appears again in the generated file name; that's because config-specific information is stored there. If you want to support multiple configs, you'll need to redo steps 2-4 with a new CMAKE_BUILD_TYPE (e.g. Debug, Release, MinSizeRel)
Step 5: Creating an example project
Let's create a simple example project now that uses GMock. First, we'll create a directory for it:
alex:~/test$ mkdir example
and now we'll go in and create some files:
alex:~/test$ cd example/
alex:~/test/example$ touch CMakeLists.txt main.cpp
Using your favorite text editor, add the following contents to main.cpp:
#include <gmock/gmock.h>
using namespace testing;
struct Example : public Test {};
TEST_F(Example, AlwaysPass) { ASSERT_THAT(0, Eq(0)); }
TEST_F(Example, AlwaysFail) { ASSERT_THAT(0, Eq(1)); }
This is as basic of a "hello world" for GMock as I could come up with. It has one test that always passes and another that always fails (just so we can see the various outputs).
Now we'll write the build script in CMakeLists.txt:
cmake_minimum_required(VERSION 3.23)
project(example)
find_package(GTest REQUIRED)
add_executable(example main.cpp)
target_link_libraries(example PRIVATE GTest::gmock_main)
Once again, this is as simple as can be.
The first two lines are required boilerplate. They must always1 appear as the first two lines of your project, in that order, with nothing before or in between.
The first command, cmake_minimum_required, tells CMake which set of backwards-compatibility policies to enable. It does not put CMake into an emulation mode or anything like that. You must test your build with the version written there because CMake will not stop you from using features that are too new for the declared minimum version.
The second command, project, names your project and kicks off CMake's compiler detection routines.
Next, we tell CMake that this project depends on the GTest package by issuing find_package(GTest REQUIRED). The REQUIRED argument kills the configure step if the package cannot be found. The name GTest is derived from the GTestConfig.cmake file. For any CMake project XYZ, its main package file must be named either XYZConfig.cmake or XYZ-config.cmake.
Finally, we add our test executable example and link it to the target GTest::gmock_main. This target provides a main function in addition to the GMock standard library. If you want to write your own main, then link to GTest::gmock instead.
1. with very few exceptions that are hardly worth mentioning
Step 6: Building and running the example
Now we're finally ready to build and run the example. Let's go back up to our working directory:
alex:~/test/example$ cd ..
alex:~/test$
And now we'll go ahead and configure the build:
alex:~/test$ cmake -S example -B _build/example -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH=$PWD/_local
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found GTest: /home/alex/test/_local/lib/cmake/GTest/GTestConfig.cmake (found version "1.11.0")
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/_build/example
Note the -DCMAKE_PREFIX_PATH=$PWD/_local flag. That's telling CMake that there are additional libraries and CMake packages in $PWD/_local and so find_package and the other find_* commands should look there. If you didn't pass this flag, you might see an error like this:
CMake Error at /usr/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR
GTEST_MAIN_LIBRARY)
Call Stack (most recent call first):
/usr/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake-3.23/Modules/FindGTest.cmake:270 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:4 (find_package)
-- Configuring incomplete, errors occurred!
See also "/home/alex/test/_build/example/CMakeFiles/CMakeOutput.log".
Now that we're configured, we can build the example:
alex:~/test$ cmake --build _build/example/
[ 50%] Building CXX object CMakeFiles/example.dir/main.cpp.o
[100%] Linking CXX executable example
[100%] Built target example
and then run it:
alex:~/test$ _build/example/example
Running main() from gmock_main.cc
[==========] Running 2 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 2 tests from Example
[ RUN ] Example.AlwaysPass
[ OK ] Example.AlwaysPass (0 ms)
[ RUN ] Example.AlwaysFail
/home/alex/test/example/main.cpp:8: Failure
Value of: 0
Expected: is equal to 1
Actual: 0 (of type int)
[ FAILED ] Example.AlwaysFail (0 ms)
[----------] 2 tests from Example (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
[ FAILED ] 1 test, listed below:
[ FAILED ] Example.AlwaysFail
1 FAILED TEST
As you can see, our passing test passed, and our failing test failed, as expected!
Step 6: CTest integration (optional)
If we want, we can integrate this with CTest for easier running of multiple GMock binaries down the line. Here's the new CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(example)
enable_testing() # ------------------------ ADDED 1
find_package(GTest REQUIRED)
include(GoogleTest) # ------------------------ ADDED 2
add_executable(example main.cpp)
target_link_libraries(example PRIVATE GTest::gmock_main)
gtest_discover_tests(example) # ------------------------ ADDED 3
Aside from the three lines marked ADDED, nothing has changed. The first added line simply enables CTest support. The second added line imports CMake's native support for Google Test. Finally, the third line tells CTest that the example executable contains GTest tests.
After making these edits, an incremental build will automatically re-run CMake.
alex:~/test$ cmake --build _build/example/
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/_build/example
Consolidate compiler generated dependencies of target example
[ 50%] Linking CXX executable example
[100%] Built target example
And now we can use the CTest runner on our build directory:
alex:~/test$ ctest --test-dir _build/example/
Internal ctest changing into directory: /home/alex/test/_build/example
Test project /home/alex/test/_build/example
Start 1: Example.AlwaysPass
1/2 Test #1: Example.AlwaysPass ............... Passed 0.00 sec
Start 2: Example.AlwaysFail
2/2 Test #2: Example.AlwaysFail ...............***Failed 0.00 sec
50% tests passed, 1 tests failed out of 2
Total Test time (real) = 0.00 sec
The following tests FAILED:
2 - Example.AlwaysFail (Failed)
Errors while running CTest
Output from these tests are in: /home/alex/test/_build/example/Testing/Temporary/LastTest.log
Use "--rerun-failed --output-on-failure" to re-run the failed cases verbosely.
And once again, we can see that our passing test passed and our failing test failed. Hooray!

CMake: find Armadillo library installed in a custom location

No root access on cluster, install Armadillo with
make install DEST_DIR=/home/my_id/include
and now I have no idea how to do find_package(ARMADILLO REQUIRED) to set ${ARMADILLO_INCLUDE_DIRS} and${ARMADILLO_LIBRARIES}.
use CMAKE_LIBRARY_PATH and/or CMAKE_PREFIX_PATH environment variables to specify additional paths where to look for libraries and headers.
Also see cmake - find_library - custom library location but all the answers there suggest to edit CMakeLists.txt that could be slightly inconvenient sometimes.
Edit: Here's the complete working example:
alex#rhyme /var/tmp $ tar zxf armadillo-6.500.4.tar.gz
alex#rhyme /var/tmp $ cd armadillo-6.500.4
alex#rhyme /var/tmp/armadillo-6.500.4 $ mkdir build
alex#rhyme /var/tmp/armadillo-6.500.4 $ cd build
alex#rhyme tmp/armadillo-6.500.4/build $ cmake ..
-- Configuring Armadillo 6.500.4
...
-- CMAKE_INSTALL_PREFIX = /usr
-- INSTALL_LIB_DIR = /usr/lib64
-- INSTALL_INCLUDE_DIR = /usr/include
-- INSTALL_DATA_DIR = /usr/share
-- INSTALL_BIN_DIR = /usr/bin
-- Generating '/var/tmp/armadillo-6.500.4/build/ArmadilloConfig.cmake'
-- Generating '/var/tmp/armadillo-6.500.4/build/ArmadilloConfigVersion.cmake'
-- Generating '/var/tmp/armadillo-6.500.4/build/InstallFiles/ArmadilloConfig.cmake'
-- Generating '/var/tmp/armadillo-6.500.4/build/InstallFiles/ArmadilloConfigVersion.cmake'
-- Configuring done
-- Generating done
-- Build files have been written to: /var/tmp/armadillo-6.500.4/build
alex#rhyme tmp/armadillo-6.500.4/build $ make -j4
Scanning dependencies of target armadillo
[100%] Building CXX object CMakeFiles/armadillo.dir/src/wrapper.cpp.o
Linking CXX shared library libarmadillo.so
[100%] Built target armadillo
alex#rhyme tmp/armadillo-6.500.4/build $ make install DESTDIR=/var/tmp/armadillo
[100%] Built target armadillo
Install the project...
-- Install configuration: ""
-- Installing: /var/tmp/armadillo/usr/include
-- Installing: /var/tmp/armadillo/usr/include/armadillo_bits
-- Installing: /var/tmp/armadillo/usr/include/armadillo_bits/spop_htrans_bones.hpp
...
-- Installing: /var/tmp/armadillo/usr/include/armadillo_bits/subview_elem2_bones.hpp
-- Installing: /var/tmp/armadillo/usr/include/armadillo
-- Installing: /var/tmp/armadillo/usr/lib64/libarmadillo.so.6.500.4
-- Installing: /var/tmp/armadillo/usr/lib64/libarmadillo.so.6
-- Installing: /var/tmp/armadillo/usr/lib64/libarmadillo.so
-- Installing: /var/tmp/armadillo/usr/share/Armadillo/CMake/ArmadilloLibraryDepends.cmake
-- Installing: /var/tmp/armadillo/usr/share/Armadillo/CMake/ArmadilloLibraryDepends-noconfig.cmake
-- Installing: /var/tmp/armadillo/usr/share/Armadillo/CMake/ArmadilloConfig.cmake
-- Installing: /var/tmp/armadillo/usr/share/Armadillo/CMake/ArmadilloConfigVersion.cmake
alex#rhyme tmp/armadillo-6.500.4/build $ cd ../../
alex#rhyme /var/tmp $ mkdir test_armadillo_project
alex#rhyme /var/tmp $ cd test_armadillo_project
alex#rhyme /var/tmp/test_armadillo_project $ cat >CMakeLists.txt <<EOF
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
FIND_PACKAGE(Armadillo REQUIRED)
EOF
Now we're trying to build the package w/o specifying its location. CMake expectedly fails:
alex#rhyme /var/tmp/test_armadillo_project $ cmake .
-- The C compiler identification is GNU 5.3.1
-- The CXX compiler identification is GNU 5.3.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at /usr/share/CMake/Modules/FindPackageHandleStandardArgs.cmake:138 (message):
Could NOT find Armadillo (missing: ARMADILLO_LIBRARY ARMADILLO_INCLUDE_DIR)
Call Stack (most recent call first):
/usr/share/CMake/Modules/FindPackageHandleStandardArgs.cmake:374 (_FPHSA_FAILURE_MESSAGE)
/usr/share/CMake/Modules/FindArmadillo.cmake:92 (find_package_handle_standard_args)
CMakeLists.txt:3 (FIND_PACKAGE)
-- Configuring incomplete, errors occurred!
See also "/var/tmp/test_armadillo_project/CMakeFiles/CMakeOutput.log".
Now we're specifying the custom path via environment variable:
alex#rhyme /var/tmp/test_armadillo_project $ CMAKE_PREFIX_PATH=/var/tmp/armadillo/usr cmake .
-- Found Armadillo: /var/tmp/armadillo/usr/lib64/libarmadillo.so (found version "6.500.4")
-- Configuring done
-- Generating done
-- Build files have been written to: /var/tmp/test_armadillo_project
I'm pretty sure I could set CMAKE_PREFIX_PATH right in CMakeLists.txt and it would work just as with environment variable above.