Why can I use CMake supplied modules (CMakeDependentOption.cmake specifically) locally, but not on CI or Docker? - c++

I have a cmake project that successfully builds locally but errors with
include could not find load file:
CmakeDependentOption
when trying to build on a CI platform or in Docker. Note that CMakeDependentOption.cmake is a script that comes with cmake itself. So it should just be available. On CI to install cmake, I wget the relevant cmake release from their downloads page, unzip it and add the bin directory to the PATH environment variable. Then I use the cmake command to build my library. The result is the above error.
I suspect this means that a CMake variable (such as "CMAKE_MODULE_PATH" but not, since this variable seems to be empty at the start of the cmake script) is messed up or not set somehow. The path to the correct file to include is
<cmake_root>/share/cmake-3.18/Modules/CMakeDependentOption.cmake
And I have verified that it exists manually. My question: is there a way to locate this directory from within cmake? Perhaps a cmake --config or cmake --libs mode (a bit like pkg-config?)
Failing that, does anybody have any suggestions as to why this is happening and how to get around it.

You can locally because most likely you don't use a linux based platform, like windows or mac. This is because linux filesystem are case sensitive. Which means CmakeDependentOption is different from CMakeDependentOption.
Docker runs containers in linux, so filenames are gonna be case sensitive, and the include is going to fail if the cases are different.

Related

What do I need to do in order to use CMake from a custom directory?

I've installed a version of CMake to /some/where/cmake, and have put /some/where/cmake/bin in the PATH.
What environment variables do I need to set, and what other actions do I need to take, in order for my custom CMake to function properly? Specifically, how do I ensure it looks in /some/where/cmake/share before /usr/share for CMake-related files?
Notes:
The OS is GNU/Linux.
I'm using CMake 3.16.6.
If I issue the CMake command message(STATUS ${CMAKE_ROOT}), I get: /some/where/cmake/share/cmake-3.16
What environment variables do I need to set, and what other actions do I need to take, in order for my custom CMake to function properly? Specifically, how do I ensure it looks in /some/where/cmake/share before /usr/share for CMake-related files?
Nothing! CMake is designed to look relative to the binary's actual location on your filesystem and otherwise ignore standard system directories for its own functioning (of course it will detect these for toolchain purposes).
I have personally installed CMake 3.1 -- 3.20 on Ubuntu Linux by just downloading and untarring the release archives here to /home/alex/bin/cmake-3.X.Y and creating corresponding symlinks cmake-3.X, ctest-3.X, and cpack-3.X in /home/alex/bin (which is in my PATH). I use these regularly to test answers I post here on StackOverflow. Took all of 5 minutes to set up.

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.

GDB not a recognized command - Windows command prompt

I am trying to use GDB to debug a C++ program, but my system is not recognizing gdb as a command. I installed it, along with many other tools, via MinGW. I have not had any problem with the other features I have used (gcc, g++), so the issue doesn't seem to be with my general set up. I have added the MinGW\bin directory to my PATH. The gdb.exe is in that folder. But it will not run when invoked from my project directory, it simply errors: "'gdb' is not recognized as an internal or external command, operable program, or batch file." Is there some step in setup or invocation that I missed for using GDB?
EDIT: Alright, I think I found the problem: there are two MinGW directories in my PATH, one at C:\MinGW, and another in folder that got installed with some Haskell compilers I used a while ago. It appears to be defaulting to the Haskell folder, perhaps because this directory is listed first. However, this folder contains gcc and g++, but NOT gdb. I was able to get the gdb command working by creating the fstab file in the msys directory, a step I apparently forgot when setting up MinGW. I added my C:\MinGW directory to it, and now the gdb command is working properly! Out of curiosity, what does this file do?
Also, ideally I would like it to look in the C:\MinGW directory first, since this is the folder I plan to keep updated, and the one that contains ALL of the various applications. However, the Haskell directory is specified via the system PATH variable, which I've read it's not a good idea to touch. Would switching the order that they appear even fix my problem?
EDIT 2: Not 100% sure what happened, but the gdb command appears to be working now. I have always been using the Windows cmd prompt to run these tools, so per the answer below (that I should not need to mess with msys) I deleted the fstab file, and lo, it still works! However, my second question above still stands: What is the best way to get the compilers to run out of C:\MinGW\bin instead of C:\Program Files (x86)\Haskell Platform\2013.2.0.0\bin? Is moving the Haskell location out of the system PATH and to the end of the user PATH a viable option?
I had to run pacman -S mingw-w64-x86_64-gdb separately and then gdb showed up in the bin.
You do not have to run gdb (or gcc and all other MinGW tools for that matter) within msys - it is not like Cygwin in that respect. Had you run it from the Windows cmd console, it should work.
The msys shell is useful for running configure scripts generated by Autoconf used by many Linux originated open source projects, but its environment is independent of the Windows environment.

mingw-w64-v2.0.6.tar.gz - define environment variables path

I download the latest version of minGW - mingw-w64-v2.0.6.tar.gz . Then I extract in into C:\MinGW . As I saw in some articles, now I have to define the path under environment variables .
In C:\MinGW now have -
I tried to set the variable value of path as C:\MinGW , but when I do in eclipse juno build path for some project I get -
make all
Cannot run program "make": Launching failed
Error: Program "make" not found in PATH
EDIT:
I downloaded GCC+binutils 64-bit ,exctract to c:\mingw64 , change the path to c:\mingw64\bin and changed the build command to mingw32-make.
Now when I build the project I get error -
mingw32-make all
mingw32-make: *** No rule to make target `all'. Stop.
2nd EDIT :
finally I succeeded to run a project by chose -
Note that it must uncheck the show project type and toolchians only if they are supported on the platform otherwise it not let to chose Executable Project type . In addition the build command should be stay on "Use default build command" .
You downloaded the source package.
You need a toolchain (GCC+binutils and maybe make/gdb). Those are located here:
32-bit
64-bit
I recommend my (rubenvb) Personal builds. They are tidy, full-featured and up to date.
After extracting the toolchain anywhere (say, D:\), add D:\mingw64\bin or D:\mingw32\bin to PATH. Or double-click on the batch scripts I include with my latest builds and it'll be done for you.
Note that you'll need to set up Eclipse for MinGW compilation, which means using mingw32-make, not make.
Lastly, I also suggest using MinGW-w64's support channels (forum and mailing list; please subscribe before posting to mingw-w64-public) in the future. I linger there, among other generally nice and helpful people.

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.