How to install a Library for C++ like Eigen and sharkML at vs code? - c++

I am trying to install libraries like eigen, sharkMl, xtensor, and others in VSCode for C++.
Please if anyone can help me to know the right way to do that.

All of these libraries use CMake for their build system so what I do is use CMake as my build system. My favorite way to do this is to use the libraries build systems to install them and then inlcude them with cmakes find_package function. This you can do by cloning the git repository for the library then build it and install it with cmake. On linux you do this by:
git clone https://gitlab.com/libeigen/eigen.git
cd eigen
mkdir build
cd build
cmake ..
sudo make install
VSCode has good integration for cmake so if you have the C/C++ Extension pack you will be able to build with cmake. In your project folder make a CMakeLists.txt file and add the packages you want:
add_executable(main main.cpp)
find_package(Eigen3 3.4 NO_MODULE)
target_link_libraries(main Eigen3::Eigen)
(This example assumes the main cpp file is main.cpp and creates an executable called main) Then when you press ctr+shift+p and perform CMake: Configure you can select your compiler and build the executable.

Related

reference dynamic libraries using relative path in CMakeLists

I have a project using some dynamic libraries. The generated executable runs well on my local machine. However, if I share it with others, the executable will still try to find dynamic libraries with the absolute path in my local machine, which of course do not exist in other machines. How can I resolve this issue by changing CMakeLists?
My current CMakeLists.txt file:
cmake_minimum_required(VERSION 3.24)
project(MyProject)
link_directories("libs/mac_arm64")
add_executable(MyProject main.cpp)
target_link_libraries(MyProject expat bz2 z geos_c)
When CMake builds libraries and executables, it (by default) embeds absolute RPATH into them. This allows to successfully find all libraries when run those executables on the build machine.
But those libraries and executables, which are created in the build tree, are not intended to be copied to other machine.
Instead, you should install those libraries and executables. Upon installation CMake strips their hardcoded RPATHs, which allows to distribute them.
Add to your CMakeLists.txt:
install(TARGETS MyProject DESTINATION bin/)
and build it with
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=../install
make
make install
This will install your project into install directory near the build. After installation you could pack content of install directory and send it to your customers/friends/whoever. CMake even provides cpack tool for easy packaging an installed project.
More about RPATH settings in CMake can be found in their wiki.

How to install a cpp library using cmake on Windows x64?

I'm using CLion with MinGW-GCC on the Windows-x64 platform - This is the background of the problem.
I was trying to install gtest before. But a lot of confusion arose in the middle.
First time I ran those commands(in googletest-release-1.12.1\) according to the instructions of googletest-release-1.12.1\googletest\README.md:
mkdir build
cd build
cmake ..
But I got error messages like:
CMake Error at CMakeLists.txt:51 (project):
Failed to run MSBuild command:
C:/Windows/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe
to get the value of VCTargetsPath:
Then I changed my last command to
cmake -G "MinGW Makefiles" ..
because I use make provided by MinGW. I don't know whether it's right but, it ran properly.
then I called
make
make install
make ran smoothly. But when I ran make install, I got these messages:
Install the project...
-- Install configuration: ""
-- Installing: C:/Program Files (x86)/googletest-distribution/include
CMake Error at googlemock/cmake_install.cmake:41 (file):
file INSTALL cannot make directory "C:/Program Files
(x86)/googletest-distribution/include": No such file or directory.
Call Stack (most recent call first):
cmake_install.cmake:42 (include)
make: *** [Makefile:109: install] Error 1
I have no idea at all this time. So I changed my way. According to this answer, I copied the whole library into my project and edited CMakeLists.txt like this:
cmake_minimum_required(VERSION 3.23)
project(gtest_study)
set(CMAKE_CXX_STANDARD 20)
add_subdirectory(googletest-release-1.12.1)
include_directories(googletest-release-1.12.1/googletest/include)
include_directories(googletest-release-1.12.1/googlemock/include)
add_executable(gtest_study main.cpp)
target_link_libraries(gtest_study gtest gtest_main)
target_link_libraries(gtest_study gmock gmock_main)
So my questions are:
Is there any difference between the two which build it using make and cmake metioned firstly, and just use commands like include_directories and target_link_libraries in CMakeLists.txt? (maybe like .h and .dll file? Or just completely the same? I don't know)
When I use make install to install a library on Windows, what should I do in particular? Specify some directory (I don't know which one) or what?
Although in my system environment I use MinGW-makefile, in CLion which the libraries are eventually used, I use ninja as the generator for CMake (it just comes with CLion, not installed for the system). Do I have to specify it and how? (-G "Ninja"doesn't work in my native env)
The difference between
cmake ..
and
cmake -G "MinGW Makefiles" ..
Is the choice of generator: The former uses the default generator, the latter uses the generator you specified. (cmake --help should put a * next to the default generator.)
Based on the error message I assume this is a visual studio generator and you may not be able to run that one properly from within a MinGW terminal.
In the latter case the default install directory seems to be based on the target OS (Windows) but does not seem to incorporate the fact that you're running from a MinGW terminal where the default install path (C:/Program Files (x86)/googletest-distribution) is not valid.
You could try to fix this by providing it during cmake configuration (passing -D 'CMAKE_INSTALL_PREFIX=/c/Program Files (x86)/googletest-distribution' before the source dir) or by providing the install directory during the installation.
The following process should allow you to install the lib. I'm using my preferred way of building here, i.e. not using build system dependent commands, but using cmake to run the build/install commands. I assume the working directory to be the root directory of the gtest sources:
cmake -G "MinGW Makefiles" -S . -B build
cmake --build build
cmake --install build --prefix '/c/Program Files (x86)/googletest-distribution'
The last command needs to be run with admin privileges, the first 2 I don't recommend running as admin. You could instead install to a directory where you do have the permissions to create directories even without admin privileges.
The difference between using the process described above and using add_subdirectory is that the former results in a installation on the system which can be used via find_package and the google test libs won't be rebuilt for every project where you do this.
...
project(gtest_study)
...
# you may need to pass the install location via -D CMAKE_PREFIX_PATH=<install_location> during configuration for this to work
find_package(GTest REQUIRED)
target_link_libraries(gtest_study PRIVATE GTest::gtest_main GTest::gmock)
The latter builds the google test project as part of your own project build and for every project where you use this approach a seperate version of the google test libs is built. Note: there should be no need to specify the include dirs yourself, since this kind of information is attached to the cmake target and gets applied to the linking target automatically:
#include_directories(googletest-release-1.12.1/googletest/include)
#include_directories(googletest-release-1.12.1/googlemock/include)
add_executable(gtest_study main.cpp)
target_link_libraries(gtest_study PRIVATE gtest_main gmock)
As for 3.: The CMake generator used for building GTest should be independent of the generator of the project using it. The thing that's important is that the compilers used by the build systems are compatible. I cannot go into detail about this, since I've never used CLion and therefore have too little knowlege about the compilers used by it. (Personally I'm working with Visual Studio on Windows.)

How can I add all Boost libraries as include directories?

I'm pulling in Boost using CPM to build another dependency of my project.
CPMAddPackage(
NAME Boost
VERSION 1.77.0
GITHUB_REPOSITORY "boostorg/boost"
GIT_TAG "boost-1.77.0"
)
The issue I'm having is exposing the header files to my dependency. I dumped all of the cmake variables, and there are many variables like boost_accumulators_SOURCE_DIR, boost_algorithm_SOURCE_DIR, boost_any_SOURCE_DIR, boost_asio_SOURCE_DIR, etc. My dependency depends on many of these libraries, and it's really tedious to list them all as include directories:
target_include_directories(
nghttp2_asio
PRIVATE "${boost_system_SOURCE_DIR}/include"
PRIVATE "${boost_config_SOURCE_DIR}/include"
PRIVATE "${boost_asio_SOURCE_DIR}/include"
PRIVATE "${boost_throw_exception_SOURCE_DIR}/include"
PRIVATE "${boost_assert_SOURCE_DIR}/include"
PRIVATE "${BoostAlign_SOURCE_DIR}/include"
PRIVATE "${boost_date_time_SOURCE_DIR}/include"
)
Is there a better way to do this?
CPM is just a thin layer around FetchContent, which in turn downloads your dependency into your build folder and then attempts to add_subdirectory it, adding it to your main build.
I think this is a bad idea for a lot of reasons...
Boost is one of the most commonly packaged C++ libraries, period. Integrating your project into an existing environment (like a Linux distro, or another package manager like Conan or Vcpkg) is going to be difficult if not impossible (without patching, I mean) since it will surely want your project to use the curated build of Boost.
Adding any third party CMake code to your own build is signing up for headaches... have you noticed how hard it is to write correct CMake code? What if Boost clobbers your cache variables or defines targets that conflict with yours?
CMake has built-in and standard support for locating many versions of Boost, including the newer versions that provide first-party CMake config modules.
Boost now provides first-party CMake config modules.
I don't think any build using Boost should be any more complex than this:
cmake_minimum_required(VERSION 3.22)
project(boost-usage-example)
find_package(Boost 1.77 REQUIRED system date_time)
add_executable(nghttp2_asio main.cpp ...)
target_link_libraries(
nghttp2_asio
PRIVATE
Boost::boost # all header-only libs: config asio throw_exception assert align
Boost::date_time
Boost::system
)
See the documentation here: https://cmake.org/cmake/help/latest/module/FindBoost.html
You only list as components (after REQUIRED) the non-header-only libraries. Those are also the ones that require special addition via target_link_libraries. Link to Boost::boost to get all the header-only modules.
This will work no matter what package manager you're using.
If you want to use vcpkg, create a file called vcpkg.json in your project root with the following contents:
{
"name": "boost-usage-example",
"version-string": "0.1.0-dev",
"dependencies": [
"boost-system",
"boost-config",
"boost-asio",
"boost-throw-exception",
"boost-assert",
"boost-align",
"boost-date-time"
]
}
You can also depend on just boost and it will acquire all boost modules, not just the ones you need. Then acquire vcpkg:
$ git clone https://github.com/microsoft/vcpkg.git
$ ./vcpkg/bootstrap-vcpkg.sh
Then build with:
$ cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$PWD/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release
$ cmake --build build
Done!
Suppose on the other hand that you wanted to use Conan. No big deal, just install Conan in a pip virtual environment:
$ python3 -m venv venv
$ . venv/bin/activate
$ python3 -m pip install -U pip setuptools wheel
$ python3 -m pip install conan
Then create a conanfile.txt with the following contents:
[requires]
boost/1.77.0
[generators]
cmake_paths
Install the dependencies:
$ mkdir build && pushd build && conan install .. && popd
And then build, using Conan's generated toolchain file:
$ cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$PWD/build/conan_paths.cmake -DCMAKE_BUILD_TYPE=Release
$ cmake --build build
In fact, you can provide both a vcpkg.json and a conanfile.txt and your users will be free to use either one or neither and rely on their system package manager or a package manager you don't know about. In any case it will just work and you free yourself of a mountain of maintenance burdens.

Install eigen3.3.7 on MacOS

I am trying to build a program on MacOS and that program requires Eigen version <= 3.3.7 but mine has 3.3.8 with brew install eigen
I went to Eigen website but 3.3.7 source is no longer available anymore.
Any workaround?
Thanks a lot!
Updates: thanks a lot but I am still very confused with how to proceed. Below is the information of the installation details and directory info.
The directory of the program source code that I want to build look like:
program
cmake
Cmakelist.txt
build
the program has the following instructions:
Create the build directory in the source tree root
mkdir build
Configure cmake, from the build directory, passing the Shogun source root as an argument. It is recommended to use any of CMake GUIs (e.g. replace cmake .. with ccmake ..), in particular, if you feel unsure about possible parameters and configurations. Note that all cmake options read as -DOPTION=VALUE.
cd build
cmake [options] ..
Compile
make
Install (prepend sudo if installing system-wide), and you are done.
make install
Sometimes you might need to clean up your build (e.g. in case of some major changes). First, try
make clean
Then I have downloaded eigen3.3.7, where the INSTALL file is as following. How should I proceed?
Method 1. Installing without using CMake
****************************************
You can use right away the headers in the Eigen/ subdirectory. In order
to install, just copy this Eigen/ subdirectory to your favorite location.
If you also want the unsupported features, copy the unsupported/
subdirectory too.
Method 2. Installing using CMake
********************************
Let's call this directory 'source_dir' (where this INSTALL file is).
Before starting, create another directory which we will call 'build_dir'.
Do:
cd build_dir
cmake source_dir
make install
You can install Eigen 3.3.7 by compiling the source code(available here).

How to compile googletest on windows using mingw with msys?

My need is simple. I have to compile and use googletest on windows using MinGW with msys. Has anyone some experience doing this?
Thanks for answers.
It took me some time but I figured it out. Here is the guide for anyone who face the same problem.
To be able to compile GoogleTest on Windows follow this instructions:
I assume you have MinGW with MSYS istalled.
Download and install CMake from the official site http://www.cmake.org/. Use the Win32 installer
version. Once you have completed the installation process copy executable files from
"xxx/CMake/bin" to "xxx/MinWG/bin".
Download and install Python from http://www.python.org/. Again, the Windows installer does the job
fine.
Once you have completed the installation process copy the "python.exe"
form python folder to
"xxx/MinWG/bin".
Download the latest stable GoogleTest from http://code.google.com/p/googletest/ and unpack it into some folder.
Run MSYS terminal and execute following commands.
cd xxx/gtest-x.x.x
cmake -G "MSYS Makefiles"
make
If you have compilation errors from pthread follow these instructions.
Copy the include folder "xxx/gtest-x.x.x/include" into your MinGW gcc include.
Copy the library files "xxx/gtest-x.x.x/*.a" into your MinGW gcc lib.
When you compile tests add "-lgtest" parameter to gcc.
EDIT
Commentators are right. The coping of executables worked for me but generaly it is not a good practice. Try to use a symbolic link instead.
To build libgtest.a without cmake/python, but only using mingw make, gtest now has a 'make' folder with a plain old makefile in it.
Make sure, mingw\bin is in the path (try running 'g++' or something).
Enter the gtest 'googletest\make' folder and run 'make'.
To test, run 'sample1_unittest' (gtest sample test output should appear).
To generate the library 'libgtest.a', run 'ar -rv libgtest.a gtest-all.o'
The library created is a full static library with no dll's generated.
That should be all.
By the way, this also works for building googlemock, just enter the googlemock folder instead of googletest, and follow the same procedure.
The question was asked in 2011 and answer with most votes is also answered the same year. So, a fresh answer would improve the question effectiveness.
Tools You need & I tested with:
Mingw64 8.0.2
GoogleTest GitHUb Source Code repo branch 1.10.0
CMake 3.20.4
and Windows10
Steps
Install the mingw64 by double clicking and chose the path which does
not have space between directory names e.g. "Program Files"
Open settings of the windows and then search environment variables
and oepn the dialog box to edit the Path environment variable
Add the mingw64/bin directory name in the Windows Path Environment
variable e.g. C:\Users[USERNAME]\mingw64\bin (replace [USERNAME]
with your username e.g. Michael or Lee etc)
Install CMake. It is double click install procedure. Make sure, its
bin directory path is added in the Path Environment Variable.
It would be installed in C:/Program Files/...
Download GoogleTest repo extract it and create a build directory
inside the extracted directory.
Execute the following commands
$ cd build
$ cmake .. -G "MinGW Makefiles"
$ mingw32-make.exe
Copy the four static libraries(*.a) from build directory
[ex: C:\Users[USERNAME]\sourcecodes\googletest-master\build\lib]
into lib of MingW64
[ex: C:\Users[USERNAME]\mingw64\x86_64-w64-mingw32\lib]
Go to the GoogleTest extracted repo, navigate to
[ex
C:\Users[USERNAME]\sourcecodes\googletest-master\googletest\include\gtest]
Copy that whole gtest directory and copy to the folder
C:\Users[USERNAME]\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include
You are done to go. You can build and link Googltest with your C++ project. I also paste a CMakelists.txt sample
cmake_minimum_required(VERSION 3.12)
project(ProjectName VERSION 1.0.0 LANGUAGES CXX)
include_directories(include)
set(SOURCES src/library.cpp include/library.h)
add_executable(libabc ${SOURCES})
#############
## Testing ##
#############
enable_testing()
find_library(GTest gtest)
add_executable (unitTest test/unit_test.cpp)
target_link_libraries (unitTest gtest gtest_main)
add_test(AllFactTest unitTest)
I hope it would work.
From the README of https://github.com/google/googletest/tree/master/googletest
:
When building Google Test as a standalone project, the typical workflow starts
with:
mkdir mybuild # Create a directory to hold the build output.
cd mybuild
cmake ${GTEST_DIR} # Generate native build scripts.
If you want to build Google Test's samples, you should replace the last command
with
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
As alternative it is also possible to build googletest using the usual MSYS/Mingw make.
So here is my alternative way:
Make sure MSys/MingW is installed on your Windows and the PATH environment is set to it
Open a cmd window - you can set the PATH explicitly here as well
CD to the unzipped googletest directory
Call configure with sh (part of MSys): sh configure
Call make -> libgtest.a should be built. It is placed in your googletest-directory lib/.libs subdirectory
See README of googletest of how to integrate the libgtest.a to your system. Also see googletest primer in the googletest wiki of how to compile. Alternatively specify the library path for gcc -L<googleTestDir>/lib/.libs and add -lgtest to link with your test project executable.
When using ASSERT_DEATH macro to check for asserts in your tested code (meaning asserts in your lib or application, not in googletest), call SetErrorMode - example main:
#include <windows.h>
#include "gtest/gtest.h"
int main (int argc, char** argv)
{
// this prevents annoying error message boxes popping up
// when assert is called in your program code
SetErrorMode(SEM_NOGPFAULTERRORBOX);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
You don't need to copy the binaries as long as you have them in your path. Install python and CMake. Test them in your msys (MinGW console)
which cmake
which python
If you see the path, then you have the binaries. If not, add their path to your Environmental Variables>PATH or just update within msys (update installation paths if necessary)
export PATH=$PATH:/c/Program Files (x86)/CMake/bin/cmake.exe:/c/Python27/python.exe
Then you can build as suggested:
cd xxx/gtest-x.x.x
cmake -G "MSYS Makefiles"
make
Test if everything works:
cd make
make
./sample1_unittest.exe
With MSYS2, simply install the mingw-w64-x86_64-gtest package:
pacman -S mingw-w64-x86_64-gtest
Then compile tests with the flags -lgtest -lgtest_main.