How to set rpath origin in cmake? - cmake

I found Cmake: How to set rpath to ${ORIGIN} with cmake but my cmake does not have target_link_options.
I'm not installing the binary, I'm only "installing" it with RUNTIME_OUTPUT_DIRECTORY, so I don't think CMAKE_INSTALL_RPATH will work. Even though, I tried SET(CMAKE_INSTALL_RPATH "$\{ORIGIN\}") as suggested in the question, but I got
Syntax error in cmake code at
.../CMakeLists.txt:25
when parsing string
$\{ORIGIN\}
Invalid escape sequence \{
I need to set this rpath which I was using in Makefile:
-rpath=\$$ORIGIN/lib
How to do it in cmake?

Following works for me on 3.14
set(CMAKE_INSTALL_RPATH $ORIGIN)
This is what Craig Scott recommended in his CppCon 2019 talk Deep CMake for Library Authors (Slide 100/110)

You need to escape $ sign not the brackets please see https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling
This works for me:
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH "\${ORIGIN}")

Related

CMake find_package: where did it find the package?

In my CMake package, there is a call to find_package. This succeeds, great! However, it turns out to be the wrong version of the package. I now want to go and delete that package. However, I have no idea where the heck it is on my system, nor where the -config.cmake file is that CMake must have found somewhere. Is there a way to get find_package to give me this information? Or at least verbosely tell me where it is searching?
I though this might be in the variable CMAKE_MODULE_PATH, however that is empty for me. So I guess it is in the default paths somewhere. But CMake searches a lot of places for packages, and I didn't find it in the usual locations that I remember.
Ah ok, I found a solution here:
https://riptutorial.com/cmake/example/21128/debug-find-package---errors
Turns out there is a special debug flag to make find_package tell you where it is searching:
cmake -D CMAKE_FIND_DEBUG_MODE=ON ..
As of CMake 3.17, the cmake command line has native support for printing the search directories for all of the CMake find_* commands. Use the --debug-find flag:
cmake --debug-find ..

Why does CMake ignore exported CXX and CC environment variables?

I am running a CMake (3.4.3) like this as explained in the CMake FAQ's:
export CC="cc_args.py $PWD/../bin/gcc"
export CXX="cc_args.py $PWD/../bin/g++"
cmake -DCMAKE_BUILD_TYPE=Debug ..
However when I print CMAKE_CXX_COMPILER and CMAKE_C_COMPILER it still points to the system's default compilers in /usr/bin. It only works when I explicitly read-in the environment variables like this:
IF (NOT $ENV{CC} STREQUAL "")
SET(CMAKE_C_COMPILER $ENV{CC})
ENDIF ()
IF (NOT $ENV{CXX} STREQUAL "")
SET(CMAKE_CXX_COMPILER $ENV{CXX})
ENDIF ()
But even then the building fails with this message:
/bin/sh: 1: /home/peterg/bin/cc_args.py /home/peterg/Code/build/../bin/g++: not found
However I am certain that all paths are correct since executing just the path between the two colons outputs this as expected:
g++: fatal error: no input files
compilation terminated.
Update:
It seems the compiling process does not like spaces in the compiler paths. I've now created two scripts (one for GCC and one for CC) which wrap the commands and propagate the arguments and that seems to work. But it still seems I am doing something fundamentally wrong because CMake would also not accept the exported CC=proxy_script_cc.sh and GCC=proxy_script_gcc.sh variables without spaces by itself.
Turning my comment into an answer
Problem
I've given you code a try and could reproduce your problem
CMake Error at [...]/cmake-3.5/Modules/CMakeDetermineCXXCompiler.cmake:56 (message):
Could not find compiler set in environment variable CXX:
cc_args.py [... PWD ...]/../bin/g++.
If I look at CMakeDetermineCXXCompiler.cmake code and at get_filename_component() documentation, it just means that it didn't find cc_args.py in "the system search path" or relative to your binary output directory.
Solution
So it does work when you give a full path or a relative path to your binary output dir with something like
export CC="../cc_args.py ../bin/gcc"
export CXX="../cc_args.py ../bin/g++"
Alternative
CMake does allow to define "launcher scripts" e.g. with CMAKE_<LANG>_COMPILER_LAUNCHER
$ cmake -DCMAKE_BUILD_TYPE=Debug
-DCMAKE_C_COMPILER_LAUNCHER=../cc_args.py
-DCMAKE_CXX_COMPILER_LAUNCHER=../cc_args.py
..
References
How to Use CCache with CMake?
Save and reprint warnings for successfully-compiled files on subsequent builds?
Pass -DCMAKE_CXX_COMPILER=<path/to/compiler> to your CMake call. That's less error prone compared to fiddling with shell variables.

Linking GLEW with CMake

How can you link GLEW to a project with CMake?
We've been trying to link GLEW to our project using CMake for at least 3 hours without any success so any help is accepted.
I'm using the FindGLEW.cmake which comes with CMake 3.1.0
CMakeLists.txt
find_package(GLEW REQUIRED)
if (GLEW_FOUND)
include_directories($(GLEW_INCLUDE_DIRS))
endif()
Environment Variables
I'm using MinGW w64 to compile the sources and we successfully linked GLFW and GLM just by copying the includes and libs to their respective folders, but after doing the same with GLEW, CMake still couldn't find it.
Sorry if I wasn't clear enough while formulating the question. I will provide any additional information required.
Edit: I've managed to link the header files by specifying their location in the CMake Cache file, though I'm getting undefined reference to glew functions like glewInit().
Typical CMake scripts like FindGLEW will define variables that specify the paths and files that your project needs. If the script can't automatically identify the correct paths (usually because of nonstandard install location, which is fine), then it leaves these variables up to you to fill in.
With command line CMake, you use the -D flag to define and set the value of a given variable. Other CMake interfaces, like CMake-gui or an IDE integration, give you this ability some other way.
However you do it, you can also modify the cache directly (CMakeCache.txt) and see what CMake is using in there or just clear the cache altogether. You'll have to rerun CMake for it to pick up your changes.
When it comes to linking, that's when you need to tell CMake which libs to link. Use the link_libraries command with what the automated script gives you.
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
link_libraries(${GLEW_LIBRARIES})
Other answers do obviously work, but the target based style of cmake makes it even easier since the GLEW find module defines the imported target GLEW::GLEW. All you need is:
find_package(GLEW REQUIRED)
target_link_libraries(YourTarget GLEW::GLEW)
YourTarget is the target that you created with add_executable or add_library. No need to explicitly add include directories, they are added automatically by linking the targets.
The secret of find_package(GLEW) is in FindGLEW.cmake file with cmake install.
find_path(GLEW_INCLUDE_DIR GL/glew.h)
find_library(GLEW_LIBRARY NAMES GLEW glew32 glew glew32s PATH_SUFFIXES lib64)
The find_path and find_library commands find paths in standard system paths. If you want them to find paths in user defined directories, you should tell them.
For example:
set(CMAKE_PREFIX_PATH "d:/libs/glew-1.10.0")
set(CMAKE_LIBRARY_PATH "d:/libs/glew-1.10.0/lib/Release/Win32/")
find_package(GLEW REQUIRED)
Reference:
http://www.cmake.org/cmake/help/v3.0/command/find_path.html
http://www.cmake.org/cmake/help/v3.0/command/find_library.html
I was struggling hard to link glew to cmake through command line on mac. This might be helpful but I am not sure :) I will walk you through step by step of what I have done.
I installed Cmake source from the web.
Then I went inside the cmake folder in terminal and typed
./bootstrap && make && make install
(this will install cmake command line tools on our OS platform)
I have some exercise files. I want cmake to generate xcode files for me for all those exercise files (ex. triangles.cpp, shader.cpp etc) So i made a directory inside exercise files folder.
$ mkdir xcode
$ cd xcode
$ cmake -G "Xcode" ..
At this point, Cmake suppose to install all xcode files that included correct libraries. But there was an error :
$ cmake -G "Xcode" ..
CMake Warning (dev) at CMakeLists.txt:3 (cmake_minimum_required):
Compatibility with CMake < 2.4 is not supported by CMake >= 3.0.
This warning is for project developers. Use -Wno-dev to suppress it.
system name is: Darwin-14.1.0
system processor is: x86_64
-- Could NOT find GLEW (missing: GLEW_INCLUDE_DIR GLEW_LIBRARY)
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
-- Using Cocoa for window creation
-- Using NSGL for context creation
-- Building GLFW only for the native architecture
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
GLEW_LIBRARY
linked by target "TextureLoader" in directory /Users/Mydir/Desktop/Exercise/Exercise Files
-- Configuring incomplete, errors occurred!
Then to make sure I have installed GLEW and all its libraries correctly, I ran
$brew install glew
Yes, I have installed glew already but it was NOT linked. See the Warning below:
Warning: glew-1.12.0 already installed, it's just not linked
Then I ran the following commands:
$ brew unlink glew
$ brew link glew
And I have solved the error. So just make sure that you have linked glew. Hope this helps.
Happy Coding :)
Finally I found a simple and short CMakeLists which works if you have installed everything in default paths.(openGL, glfw and glew)
cmake_minimum_required(VERSION 3.3)
project(openGL_tutorial)
find_package(OpenGL REQUIRED)
if(NOT OPENGL_FOUND)
message("ERROR: OpenGL not found")
endif(NOT OPENGL_FOUND)
set(GL_LIBRARY GL GLU X11)
add_executable(openGL_tutorial main.cpp)
target_link_libraries(openGL_tutorial glfw GLEW libGLEW.so libGLU.so libGL.so)
For what it is worth, in 2023, this works for me, on macOS, with GLEW, GLFW, and CMake installed using Homebrew:
cmake_minimum_required(VERSION 3.10)
project(Project)
add_executable(Project main.cpp)
find_package(glfw3 REQUIRED)
find_package(GLEW REQUIRED)
target_link_libraries(Project glfw GLEW::glew)

Error with Ogre and CMake

I installed Ogre3D 1.8.1 (the source package) on Ubuntu 12.04 and everything went fine (I managed to run some samples on the Ogre interface). However, I hit a problem while I was compiling an external project (that one) that needed the OpenCV, ArUco and Ogre librarys. When I run the CMake of the project, I receive the following:
CMake Error at CMakeLists.txt:46 (find_package):
By not providing "FindOGRE.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "OGRE", but
CMake did not find one.
Could not find a package configuration file provided by "OGRE" with any of
the following names:
OGREConfig.cmake
ogre-config.cmake
Add the installation prefix of "OGRE" to CMAKE_PREFIX_PATH or set
"OGRE_DIR" to a directory containing one of the above files. If "OGRE"
provides a separate development package or SDK, be sure it has been
installed.
-- Configuring incomplete, errors occurred!
I know where the FindOGRE.cmake is, it's in the /usr/local/lib/OGRE/cmake, but I don't know how to say to CMake to look for that folder and fix this problem.
You just need to use the -D command line option along with the CMAKE_MODULE_PATH variable:
cmake . -DCMAKE_MODULE_PATH=/usr/local/lib/OGRE/cmake
Just for the record, an alternative solution would be to add the module path directly in the CMakeLists.txt. For example (tested on Debian 9):
set(CMAKE_MODULE_PATH "/usr/share/OGRE/cmake/modules/;${CMAKE_MODULE_PATH}")
Just make sure to add the line before find_package is called.
For me, it only works to set the following in CMakeLists.txt before find_package:
set(OGRE_DIR /usr/share/OGRE/build/sdk/CMake)
Note that the CMake directory is the one containing OGREConfig.cmake. For some reason, my CMake ignores CMAKE_MODULE_PATH.
Maybe, of some help for someone
For me, this solution work on manjaro:
set(CMAKE_MODULE_PATH "/usr/lib/OGRE/cmake;${CMAKE_MODULE_PATH}")
find_package(OGRE QUIET)
if (OGRE_FOUND)
include_directories( ${ogre_INCLUDE_DIR})
link_directories(${OGRE_LIBRARIES})
message(STATUS "OGRE: FOUND")
else()
message(STATUS "OGRE: NOT FOUND")
endif()

CMake set library search path fails in testCXXCompiler

I built my own GCC and libraries and put the libraries in /opt/gcc-4.6.2/lib so generically-named libraries like libstdc++ do not interfere with other parts of the system. This means I have to specify the library search path manually:
$> g++-4.6.2 -L/opt/gcc-4.6.2/lib input.cpp
When trying to get my project to build with CMake, I can't seem to figure out how to tell CMake to search that library. The documentation says to use CMAKE_LIBRARY_PATH, which I set on the line used to generate my Makefiles:
$> cmake .. -DCMAKE_CXX_COMPILER=g++-4.6.2 \
-DCMAKE_LIBRARY_PATH=/opt/gcc-4.6.2/lib
This, however, fails on the simple program compilation test:
# blah blah blah...
/usr/local/bin/g++-4.6.2
CMakeFiles/cmTryCompileExec.dir/testCXXCompiler.cxx.o -o cmTryCompileExec
-rdynamic
/usr/bin/ld: cannot find -lstdc++
# blah blah blah...
I can't seem to find the voodoo magic needed to make CMake emit -L/opt/gcc-4.6.2/lib for the test compilation (I know CMAKE_LIBRARY_PATH works after the project is built). How can I force CMake to use an alternative library path to link the test executables?
Hmm, i'm not familiar with how gcc builds itself, but i suppose that it should know where to search for it's libs. Maybe you should try cross-compilation.
Also, CMAKE_LIBRARY_PATH will not help your problem, since it set libraries search path only for CMake, not for compiler.
So, i don't see any other way except setting CMAKE_CXX_FLAGS or CMAKE_EXE_LINKER_FLAGS to -L/opt/gcc-4.6.2/lib.