Install IPOPT locally into C++ codebase with CMake ExternalProject - c++

I would like to use Ipopt in a CMake-based project using ExternalProject. The library should be installed locally and automatically in the build folder so that the user must not go through any hassle.
I can do this for simple enough repositories that do not have many dependencies; unfortunately, this is not the case for Ipopt, whose installation requires a set of packages to be installed first.
How can install and use Ipopt in a local, self-contained way using CMake ExternalProject? If this cannot be done, is there an approach that would make the process at least partially self-contained? I would be very grateful for any answer with a working CMake script!

Related

vcpkg manifest install system wide

Just tried Vcpkg Manifest on my cmake project and it is cool, with exceptions however.
My project depends on opencv and it takes a long time for vcpkg to install opencv. So I realized I don't want vcpkg downloawding/installing opencv every time I clone the project in a different folder.
Is it possible to use Vcpkg Manifest but make it install libraries system wide instead of locally to the project?
Or at least not inside the build directory, so will be possible to reuse it?
No, you can't install libraries system-wide in manifest mode.
But binaries are cached so that if you use a library in multiple projects, you don't have to build it from scratch.
https://github.com/microsoft/vcpkg/blob/master/docs/users/binarycaching.md
I abused vcpkg's --x-install-root to achieve similar results as manifest mode.
--x-install-root= (Experimental) Specify the install root directory
Under your project folder, you can install this project's dependencies into a system global directory by using this parameter, so that all projects can share the installed packages system wide. For example, in my case, I installed all packages into $VCPKG_ROOT/installed directory like this:
vcpkg install --x-install-root=$VCPKG_ROOT/installed
You can even use vcpkg list anywhere if you (ab)use it this way.

Is there a tool for meson similar/equivalent to CPack for CMake?

I have recently started learning meson and I am testing switching to it (from CMake) in one of my projects. The problem is that I usually use cpack to build the project's packages/installers, and after scouring the meson docs for something similar to cpack I am unable to find anything.
Requirements/what I currently use cpack for
Single script to automatically build and package binary releases (such as deb, rpm, windows installer, etc)
Integrates with the build system - Picks up targets automatically, doesn't require redefining installation logic or structure
Supports building at least deb packages and a windows installer (don't care which)
There is the information on building release archives and then using scripts to process them with packaging tools (such as inno). However, this is not really what I am looking for as it is far more awkward and inflexible than cpack (i.e I have to change 3 different scripts if the directory structure changes).
Ultimately I can learn to use the meson system and manually write packaging scripts, no doubt it will make me a better scripter, however, I am eager to know if there is a better way of doing this which is not advertised in the docs or if there is some unofficial project which will automate the process.
Edit
By package I mean like a deb package - a package for a system package manager, not something like conan
I suggest that you use conan. Please take a look at conan configuration in the Meson.
It might be worth considering using meson rpm packaging module RPM module:
It autodetects installed files, dependencies and so on
This module as of now supports only generation of RPM spec file:
rpm = import('rpm')
rpm.generate_spec_template()

Does CMake has a "find-or-download-and-run-build-command" mechanism?

CMake has a find_package() backed by a bunch of FindXYZ scripts (which you can also add to).
What mechanism, if any, is available to me to tell cmake: "Find this package, and if you haven't found it, download it and trigger its build" - with the downloading and building part also backed by per-package scripts or settings (so that downloading could be with wget or git clone, building could be with cmake or maven or a package-specific command, etc.) ?
Yeah, I was bitten by that Friday.
So, CMake has an ExternalProject directive, meant for exactly that, get/update if necessary, configure, build and install this and that external project. Awesome!
Sadly, CMake isn't that awesome.
You can't use the target defined by ExternalProject as a library in target_link_libraries. I've really tried to.
The basic problem is that the updating, building and installation of the external project happens at build time, whereas CMake insists on only using libraries that it found during pre-build (i.e. during the CMake run); you can't re-detect stuff while running make/ninja/msvc… .
You can define a custom target, tell it where the .so you'd want to link against later will be, and try to coerce CMake into believing you without checking at pre-build. Sadly, at least in the CMake versions I had, that broke dependency tracking, so that it simply didn't build the external library, because nothing needed it.
From the error messages you get when trying to use an external project in target_link_library, it seems CMake assumes you'd only want to install tools you need at build time that way, not libraries. A bummer.
You can roll your own version of download-on-demand using execute_process() (which runs on the CMake configure step) with ${CMAKE_COMMAND} as the command invoked on a CMakeLists.txt containing ExternalProject_Add().
You could even either configure_file() the CMakeLists.txt to fill out custom variables or dynamically create the CMakeLists.txt file.

CMake "make install" or including a library in windows

I'm trying to create an Open Source C++ project. I want it to be as easy to build as possible, but at the same time cross platform.
I don't need gui or heavy libraries like boost or Qt, so I've settled on using GitHub, CMake, and LibSourcey.
My problem is, I can't find a way to make my project easy to build in windows, which is my development environment.
How can I "make install" a library in Windows for use in my project? Do I even have to install it in windows?
Is it possible to download, build, and link it automatically?
On windows, besides an installer, I also want to make a portable version, so don't want any hard coded library paths.
I assume, on some platforms, like Linux, libraries are built separably and packaged up by maintainers. So I shouldn't just bundle up my own copies.
So, my question is:
How can I set up a project that is cross platform and easy to build, and what are the best practices?
You can create git submodule in your git repo with path for example
contrib/LibSourcery and url to github repo of LibSourcery, because of LibSourcery uses cmake you just
need add such line into your CMakeLists.txt: add_subdirectory(contrib/LibSourcery)
So person who want to use your code, just do git clone --recursive url
to get all of your code and dependencies, after that it run cmake -G, to create project for IDE of his choice (including MSVC++ of course),
open project in IDE and press build button, that's all.
Use babun. It's a wrapper for cygwin and it works perfectly for everything I need, even compiling with cmake.
Alternatively, you could use premake, which uses lua as a config system and works fine on windows.
There is no elegant cross-platform way, since the idea of "make install" doesn't exist on Windows, therefore the use of cmake install is undefined there. For something which is supposed to help cross-platform, I feel this is a deficiency w cmake.
My solution is to write a custom _INSTALL which takes the same args as cmake install and then on Linux it just calls install, and on Windows it does an add_command which does a post-build copy to the install paths, which accomplishes the same thing. Basically, _INSTALL behaves the way you expect a cross-platform install command to behave. Can share my _INSTALL func if there is interest.
_INSTALL is placed nto a Helper.cmake, and included in all my CMakeList.txt for my projects, so all I need to do is call it and the generated lib/inc files magically appear for both win and linux.
You can use vcpkg, an open source package manager for c and c++. It allows to easily download and compile libraries and then use find_package from within CMake like you would on linux. It's very easy to use. It even provides hints as to how to alter your cmake file to use the libraries.
I started by installing packages with the command line, and then wondered why they wouldn't show up in visual studio. But I realized that it would download 32 bit libraries by default. Use .\vcpkg install <libname>:x64-windows if you need the 64 bit libraries.
After running the integrate command, you will need to delete any cmake caches to have MSVS use the new toolchain.

Building c++ project in Ubuntu Linux with Makefile.am/Makefile.in

I am new in Ubuntu/Linux and I've been working with java using the NetBeans IDE, so I don't have much experience with building c++ projects. But now I have to provide a proof of concept and I need to connect a C++ client with my ActiveMQ server. I downloaded The ActiveMQ-CPP API from this link, but I can't build/run it.
The download came with the files: Maklefile.am and Makefile.in. I searched it and I found that I need automake/autoconf to build it. I tried running ./configure but it says that it couldn't find such file or directory. I tried
sudo apt-get update
sudo apt-get install automake
sudo apt-get install autoconf
and a lot of other commands that I found on the Internet. None of then worked. I know that this question is really basic and it seems to be already answered somewhere else, but every attempt I've made failed. I think I'm missing something. I even tried the solution provided in the last message in this topic but it didn't work either.
Can anyone help me install autoconf/automake, or tell me how to use Makefile.am / Makefile.in to build the project I downloaded, or even suggest me some other way of building it?
Since you're open to other methods of building your project, I'm going to suggest CMake. It is a far better build system than autotools (at least from where I stand).
#CMakeLists.txt
project(MyProject CXX)
set_minimum_required(VERSION 2.8)
add_executable(foobar foo.cpp bar.cpp)
That example will build an executable called "foobar" by compiling and linking foo.cpp and bar.cpp. Put the above code in a file called CMakeLists.txt, then run the following commands:
cmake <path to project> #run in the folder you want to build in
make #this does the actual work
The really cool thing about CMake is that it generates a build system (Makefiles by default) but you can use it to generate project files for Eclipse, a Visual Studio solution, and a bunch of other things. If you want more information, I'd check out their documentation.
The "configure" script should be in your ActiveMQ-cpp source directory. From the Linux command line, you should be able to:
1) "cd" into your ActiveMQ* directory
2) "ls -l" to see the "configure" script
3) "./configure" to set things up for building the library\
4) "make" to actually build the library
This is mentioned in comments, but this particular point of confusion has been common for well over a decade and I think needs to be clarified as often as possible. You DO NOT need to have autoconf or automake installed to build a project that used those tools. The entire point of the autotools is to generate a build system that will build on a system using only the standard tools (make, a c compiler, sh, and few others.) Unfortunately, many developers release tarballs that do not build cleanly. If you unpack the tarball and it does not contain a configure script, or if the configure script is broken, that is a bug in the package. The solution is absolutely not to install autoconf/automake/libtool and try to produce a working configure script. The solution is to report the build error as a bug to the package maintainer.
The world would be a better place if Linux distributions stopped installing multiple versions of the autotools by default as less than .002% of the population needs those tools, and anyone who actually needs to have the tools should be capable of installing it themselves. Anyone incapable of acquiring and installing the tools has no business using them.