I have some C++ project build by autotools.
The project uses some libraries, also written by me. Source of libraries are imported to the project as submodules of git. Each library has its own autotools files.
Say, I have:
src/<my src files>
modules/libfoo/
libbar/
Makefile.am
Configure.in
<other autotools junk>
What I want is to somehow include libraries into main project compilation chain. I guess that just including subdir to Makefile.am is not enough, because some checks can be reformed in configure.am.
You can run the configure scripts in the sub-modules by adding the AC_CONFIG_SUBDIRS command to the top-level configure script. It tells the top-level script to descend into the sub directories and invoke the configure script found there. Then, you can just reference the built libraries from your Makefile.am.
Read this section of the GNU automake manual.
Related
Is it possible to specify build directory within CMakeLists file? If yes, how.
My aim is to be able to call "cmake" within top level source directory and have cmake figure out the build directory.
Afaik, with CMake the build directory is always the directory from where you invoke the cmake or ccmake command. So if you want to change the build directory, you have to change directories before running CMake.
To control the location where executables, static and shared libraries are placed once finished, you can modifiy CMAKE_RUNTIME_OUTPUT_DIRECTORY, CMAKE_ARCHIVE_OUTPUT_DIRECTORY, and CMAKE_LIBRARY_OUTPUT_DIRECTORY respectively.
By design, there is not a way to specify that in CMakeLists.txt. It is designed for the user to be able to build the project in whatever directory they want. The typical workflow is:
Check out the project source code.
Go to desired build directory, or the source dir if you plan to do an in-source build.
Run cmake or ccmake to configure the project in that build directory.
Build your project.
All of the directories specified within your CMakeLists.txt should be relative to the ${PROJECT_BINARY_DIR} and ${PROJECT_SOURCE_DIR} variables. In this way, your code becomes buildable across different platforms, which is the goal of CMake.
I have downloaded a ROS2 demo from the examples repository.
Specifically, I have used minimal_subscriber and minimal_publisher.
I have ROS2 installed in /opt/ros2 and when I build these two examples with colcon build, it generates an install/ directory with lib/, shared/ and the other usual directory structure.
I can execute and run these demos perfectly fine with my current setup in my machine, but these executables link to libraries present in /opt/ros2, so when I want to execute them in another machine without ROS2 installed or I move my ROS2 installation in my machine, the executables cannot find the shared objects.
I've added a really simple script that adds all dependencies to install/lib when building but the executables don't seem to care, they aren't looking for shared libraries in the generated lib directory, they keep trying to search in /opt/ros2.
I believe this is something I should solve in CMake and it's not ROS2 specific, so, is there any way I can tell my generated executables to search in a diferent directory? (../lib or ./lib in my case)
If you are building them yourself (assumed since you mention CMake), you can set the RPATH in CMake (docs here). Specifically set the CMAKE_INSTALL_RPATH something like:
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
If you can't rebuild them, you can set LD_LIBRARY_PATH in your environment to where the libraries are located, or you can patch the executables themselves with an updated RPATH by using patchelf.
In order to get a relative RPATH rather than an absolute RPATH, use the $ORIGIN variable in your rpath spec. See "Recommendations" the the link above for more details.
I'm creating a very small project that depends on the following library: https://github.com/CopernicaMarketingSoftware/AMQP-CPP
I'm doing what i always do with third-party libraries: i add their git repo as a submodule, and build them along with my code:
option(COOL_LIBRARY_OPTION ON)
add_subdirectory(deps/cool-library)
include_directories(deps/cool-library/include)
target_link_libraries(${PROJECT_NAME} coollib)
This has worked perfectly for libraries like Bullet, GLFW and others. However, this AMQP library does quite an ugly hack. Their include directory is called include, but in their CMake install() command, they rename it to amqpcpp. And their main header, deps/cool-library/amqpcpp.h, is referencing all other headers using that "fake" directory.
What happens is: when CMake tries to compile my sources which depend on deps/cool-library/amqpcpp.h, it fails because it's not finding deps/cool-library/amqpcpp/*.h, only deps/cool-library/include.
Does anyone have any idea how i can fix this without having to bundle the library into my codebase?
This is not how CMake is supposed to work.
CMake usually builds an entire distributive package of a library once and then installs it to some prefix path. It is then accessible for every other build process on the system by saying "find_package()". This command finds the installed distibution, and all the libs, includes etc. automagically. Whatever weird stuff library implementers did, the resulting distros are more or less alike.
So, in this case you do a lot of unnecessary work by adding includes manually. As you see it can also be unreliable.
What you can do is:
to still have all the dependencies source distributions in submodules (usually people don't bother doing this though)
build and install each dependency package into another (.gitignored) folder within the project or outside by using their own CMakeLists.txt. Let's say with a custom build step in your CMakeLists.txt
use "find_package()" in your CMakeLists.txt when build your application
Two small addition to Drop's answer: If the library set up their install routines correctly, you can use find_package directly on the library's binary tree, skipping the install step. This is mostly useful when you make changes to both the library and the dependent project, as you don't have to run the INSTALL target everytime to make library changes available downstream.
Also, check out the ExternalProject module of CMake which is very convenient for having external dependencies being built automatically as part of your project. The general idea is that you still pull in the library's source as a submodule, but instead of using add_subdirectory to pull the source into your project, you use ExternalProject_Add to build it on its own and then just link against it from your project.
I'm writing an application that relies on the Poco project. I just need a few sub modules but they use macros defined by the Poco project which are stored in a cmake folder at the root of the Poco folder structure.
I don't want to drag the whole Poco folder as I don't want to link my project to the whole Poco framework. How can I make those macros available to my project?
I'm not sure to well understand what you need. But why not simply include de file containing the macros by this way with cmake ?
include(path/to/Poco/cmake/macros.cmake)
Take the Poco project
Open the main CMakeLists.txt of Poco and comment (with #) all the add_subdirectory commands for the directories you don't need.
Try to build Poco
If it fails, add back the directories which contains the missing dependencies (in short, you might think you don't need a directory, but it might be that one of the directories you need depends on another directory)
When it builds, you can delete all the directories for which you have removed the command add_subdirectory
I recently read that "There are several ways to configure and build a project using Autotools."
Among them:
Autoconf and Autoscan:
- Makefile.in with project build rules and Makefile substitutions
Autoheader (usable in addition to all other tools)
- scans the project and generates a config.h file during project
configuration with platform specific macro definitions, no configuration
files needed
How do you build a project without "Makefile.am"? Just using Autoconf, Autoscan & maybe Autoheader.
As the link says, Makefile.in is the template for Makefile which would just have #FOO# macros for configure (via AC_CONFIG_FILES) to substitute. If the project is really simple, I can imagine it would work OK without automake.
All autoscan and autoheader do is help you build primitive configure.ac and config.h files for your project. You aren't required to use them either.