CMake Toolchain File for GHS - cmake

I am trying to create a cmake toolchain file for the GreenHills compiler.
When I am using cmake -T C:\ghs\multi506 everything works fine.
But after creating a toolchain file with the line
set(GHS_TOOLSET_ROOT C:/ghs/multi506) I get the error message:
CMake Error: No GHS toolsets found in GHS_TOOLSET_ROOT "C:/ghs/multi506/"
What is the problem?

The use of -T and GHS_TOOLSET_ROOT is finicky. This is because of trying to maintain backward compatibility with the original generator implementation of trying to find the "latest" compiler.
'-T' takes either a absolute path or a relative path.
-T C:\ghs\multi506 means that the compilers are in this directory. It will contain gbuild.exe, etcetera.
-T multi506 will append multi506 to GHS_TOOLSET_ROOT. Therefore CMake will look for gbuild.exe in C:\ghs\multi506.
If you don't use -T then auto search mode is enabled. CMake will search for directories named comp_[^;]+, which is the naming scheme Green Hills uses for its compilers, in GHS_TOOLSET_ROOT. So in this case it will be looking for something like C:\ghs\multi506\comp_20210504.
I prefer using -T with an absolute path to the compiler directory.

Related

cmake script mode what is supported and what not

I'm using cmake to build one of my projects, I see the way it installs files is calling a cmake script by cmake -P cmake_install.cmake, but the functions used in this cmake file looks different than what is documented, e.g. for shared library install target it has:
file(RPATH_CHECK FILE ... RPATH ...)
But I cannot find this file sub-command in the cmake documentation, so is there a place that have the available functions to use in script mode?
This looks like an internal command for cmake internal use.
so is there a place that have the available functions to use in script mode?
The source code is the ultimate documentation https://gitlab.kitware.com/cmake/cmake/-/blob/master/Source/cmFileCommand.cxx#L3757 .
There is no difference in available functions between -P and cmake . invocations. You can use file(RPATH_CHECK in any cmake.

How to add and use a resource in C99 project with CMake that is portable?

I am trying to create a CMake C99 project that will have an embedded resource that can be read by the project. And this project should be portable. I am actually using CLion but I think this is a just CMake question.
Ideally I would like to see a simply way to embed helloworld.txt file in the CMake project and then a way to read the contents into const char* helloword_txt = ?? variable. And then have this compile with GCC or a Microsoft C++ compiler.
I have looked at the CMakeRC.cmake project but that look like a C++ specific way. I looked at commands like ld -r -b binary -o binary.o foo.bar # then link in binary.o but that look like Linux-specific way.
I thought CMake was designed for portable projects. Is there a portable way to do this?
I doubt there is a independent resource management system available. At least, I don't know of any.
You can take a look at Qt's qrc - it is more or less portable, but introduce a Qt dependency, of course.
First I would use FILE *fopen( const char *restrict filename, const char *restrict mode ) from C99 Standard.
Then in CMake I would use install(FILES helloworld.txt DESTINATION ${CMAKE_INSTALL_BINDIR})
note: CMAKE_INSTALL_BINDIR comes from GNUInstallDirs built-in module.
Then using a bash/bat script you can always run the program from the "BIN_DIR" so the path to helloworld.txt is "."
e.g. add_executable(foo_prg ...) ... install(TARGETS foo_prg ...)
/usr/bin/foo:
#!/usr/bin/env bash
cd /usr/bin && ./foo_prg
So user can run ./foo which will "trampoline" to /usr/bin to run foo_prg binary
Note: To test without installing, you can add to CMake:
file(COPY helloworld.txt DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
note: does not work for multi-configuration build but should be easy to deduce.
note2: don't know (i.e. never tested) if we can use $<TARGET_PROPERTY:foo_prg,RUNTIME_OUTPUT_DIRECTORY> instead.

Can the object file name be changed from .obj during cmake compiler testing?

Ultimately, I'm trying to build Apache QPID to run in the HPE NonStop OSS environment (a Posix-like environment on the NonStop system). The latest version of QPID uses cmake to build so I first need to get cmake to work for that environment. My earlier attempts tried to build in OSS directly (I needed to build cmake first before trying to build QPID), but I ran into many problems there. So lately I'm trying to build in Windows using a set of cross-development tools (compilers etc.) for NonStop. I've downloaded a Windows version of cmake 2.8 (suggested by the QPID build instructions) and am trying to use that with the X-dev tools to build QPID for OSS.
One big issue I've run into has to do with how cmake does things to test compilers and so forth early on. It will invoke the compiler to create an intermediate object file from C (and/or C++) source file and after that it will invoke the compiler to link an object file from the intermediate file. It seems that cmake prefers to add .obj to file names to create the intermediate object file name. This will work OK with my cross-compiler when creating the file (the name passed with -o to the compiler) but it will not work when passing this name for link purposes. Here is a short bit of the output per the CMakeError.log file (from trying build an OSS version of cmake 2.8 itself):
Determining if the C compiler works failed with the following output:
Change Dir: C:/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp
Run Build Command:C:/cygwin/bin/make.exe "cmTryCompileExec/fast"
/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build
make[1]: Entering directory '/cygdrive/c/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp'
"C:/Program Files (x86)/CMake 2.8/bin/cmake.exe" -E cmake_progress_report C:/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp/CMakeFiles 1
Building C object CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj
/cygdrive/c/NonStop/tndm_cmplrs-j20/usr/bin/c89.exe -o CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj -c C:/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTryCompileExec
/cygdrive/c/NonStop/tndm_cmplrs-j20/usr/bin/c89.exe "CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj" -o cmTryCompileExec
c89.exe: error: Invalid input file extension"CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj".
The cross-compiler fails because it requires intermediate object files to use .o for the extension, in order to determine they are intermediate object files. There is no way to get the c89 compiler to recognize testCCompiler.c.obj as a file type it knows what to do with.
So I've been searching (trying to find a local expert, but no one in my organization knows cmake; also numerous Google searches but could not find an answer) to see if there is any way to get cmake to change the name of the output file it uses for these type of compiles and tests. I've found info and then set CMAKE_C_OUTPUT_EXTENSION in a toolchain file:
SET(CMAKE_C_OUTPUT_EXTENSION ".o")
but that has made no difference.
If I can find a way to get cmake to create object files with names like testCCompiler.c.o instead of testCCompiler.c.obj, then the c89 cross-compiler would work.
Is it possible to do this?
UPDATE: I've managed to figure out that setting CMAKE_C_OUTPUT_EXTENSION in the toolchain file doesn't help. This gets overwritten in the CMakeCInformation.cmake (depending on whether UNIX is set or not). I also tracked down that UNIX gets set to true in Platform/UnixPaths.cmake, which gets INCLUDEd by various Platform files. So I've created a Modules/Platform/OSS.cmake file which includes it to takes care of that. I'll probably need/want to add other settings there later as I determine more flags for compilers etc that should be set to specific values for the OSS environment.

Ninja equivalent of Make's "build from this directory down" feature (with CMake)?

When building a project using CMake and Make, you can execute make from a subdirectory of your build tree (i.e. from a directory below whatever directory contains your top-level Makefile), and make will (as far as I can tell) build all targets at or below that directory. This is because CMake generates a Makefile for every directory that contains targets, so when you're in a directory with targets, make finds the Makefile for building those targets.
When CMake generates Ninja files, however, it only generates one build.ninja file, which is at the top level of the build tree. So calling ninja from a directory other than the top-level directory fails (even the -f option doesn't work because ninja can't find the rules.ninja file).
Is there any way to emulate the "make-like" behavior of building targets at and below a directory? As far as I can tell, there are no Ninja targets that correspond to "all targets at and below a particular directory." (This could be emulated using phony targets named after each directory that depend on all targets at and below that directory, but CMake does not generate such targets by default.)
ninja <DIR>/all works with recent versions of Ninja (1.7.2). Version 1.3.4 does not allow this.
I could not find a reference to this on the manual. However, CMake has this documented here:
Recent versions of the ninja program can build the project through the “all” target. An “install” target is also provided.
For each subdirectory sub/dir of the project, additional targets are generated:
sub/dir/all
Depends on all targets required by the subdirectory.
sub/dir/install
Runs the install step in the subdirectory, if any.
sub/dir/test
Runs the test step in the subdirectory, if any.
sub/dir/package
Runs the package step in the subdirectory, if any.
This worked for me:
cd <build-root>
DIRECTORY=<path-relative-to-build-root>
ninja -t targets all | egrep "^${DIRECTORY}/" | egrep CXX_EXECUTABLE_LINKER | \
sed -e 's/:.*//g' | xargs ninja
ninja -t targets all - lists all targets (including target type)
egrep "^${DIRECTORY}/" - filters list of targets to only include those in desired directory
egrep CXX_EXECUTABLE_LINKER - limits the targets to just C++ executables. You can remove or tweak this to get the set of targets you're interested in.
sed -e 's/:.*//g' - removes the target type e.g. ": CXX_EXECUTABLE_LINKER"
xargs ninja - invokes ninja to build the targets
Good question. I would like to know the answer if you find it.
I am just in the process of transitioning to cmake+ninja myself.
I found that I could not create targets with the same name at different levels
(if there is a way I would be interested to know).
So I adopted a naming convention for different targets
E.g.
name - builds program or library
test.name - runs tests for the named program or library
doxygen.name - build doxygen for the named program or library
For deeper hierarchies you can do something like:
doxygen.subproject
doxygen.subproject.name
Using this pattern you can control precisely what is built but you have to issue the command from the top-level build directory.
I think after I get used to this I will find it more productive as there is no need to change directory before you build or run something and though there is sometimes a little extra typing required the shell history generally has it covered.
This is implemented under the hood by using add_custom_target() and adding appropriate dependencies. I use a macro to do this automatically so that
a macro "add_doxygen()" will add the doxygen target for the program and make the doxygen target at each higher level depend on it using add_dependencies().

How can I get cmake command from cmake-gui?

I use cmake-gui to configure OpenCV, and I want to use same configure on some other computer.
Cause I use ssh without X forwarding, so I can't use cmake-gui to configure again.
I don't kown how to use cmake to complete my configure, so I wonder that cmake-gui can generate the command use for cmake?
Is there anyway to do this?
There is an option called: Tools-> Show my Changes which displays exactly what you have configured relating to the original configuration. One version are the copy&paste command line parameters and the other version is nicely human readable.
By default you cannot do what you want because that path is stored in CMAKE_COMMAND which is an INTERNAL variable so it is not visible in the GUI. You can manually read it from the cache using a command like grep CMAKE_COMMAND CMakeCache.txt | cut -d = -f 2. Alternatively you can update your CMakeLists.txt to put the value of CMAKE_COMMAND in the cache so that you can read it using the GUI. For example:
set(USED_CMAKE_PATH ${CMAKE_COMMAND} CACHE FILEPATH
"The path to the CMake executable used to configure this project" FORCE)
Additionally if you are using the "Unix Makefiles" generator there are two targets provided for this:
rebuild_cace which is equivalent to cmake .
edit_cache which is equivalent to ccmake . or cmake-gui . depending upon your install.
Note: I used CMake version 2.8.10.2 to test this, but I expect it to work with any version.