For example, I currently have both versions 2 and 3 of the GLFW library installed on my Linux computer, named "libglfw.so.2" and "libglfw.so.3". Is it possible to tell CMake to find a specific version of GLFW (say, version 3), and it would be smart enough to look for "libglfw.so.3" or "libglfw.so.3.*" or "libglfw.so.3.*.*"? (Or something equivalent in Mac and Windows)
I found these lines but I haven't tested it
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3) # or glfw2
Related
I'm using CMake 3.16, with a CMakeLists.txt file specifying a minimum CMake version of 3.9. In my file, I have:
find_package(CUDA 8.0 REQUIRED)
find_package(OpenCL REQUIRED)
# etc. etc.
target_link_libraries(my_executable
PRIVATE
cuda # The NVIDIA CUDA driver API
${CUDA_LIBRARIES}
OpenCL::OpenCL
)
Now, in the CMake generation phase, I get the error:
CMake Warning at CMakeLists.txt:44 (add_executable):
Cannot generate a safe runtime search path for target my_executable because
files in some directories may conflict with libraries in implicit
directories:
runtime library [libOpenCL.so.1] in /usr/lib64 may be hidden by files in:
/usr/local/cuda/lib64
Some of these libraries may not be found correctly.
Now, I do want the libOpenCL.so.1 from the CUDA directories; and building does produce an executable with the correct dependency. How can I tell CMake that this masking is ok, and not have it print the warning message?
Note: Working with CUDA in CMake has changed a lot over the 3.x series of releases. So whatever was happening before 3.8 is irrelevant, and also things changed significantly in 3.17 with a few more non-trivial changes afterwards. Answers about pre-3.8 and 3.17-or-later are, well, fine - but not what I need.
I know this doesn't answer your question precisely, but as of CMake 3.17+, the CUDA OpenCL libraries are loaded by the FindCUDAToolkit module. It is used like so:
cmake_minimum_required(VERSION 3.17)
project(my_proj LANGUAGES C CXX CUDA)
find_package(CUDAToolkit 8.0 REQUIRED)
# ...
target_link_libraries(
my_executable
PRIVATE
CUDA::cuda_driver
CUDA::cudart
CUDA::OpenCL
)
I hope this answer will help other readers who are using up-to-date CMake, because whatever answer works on 3.9 will not be quite as nice.
As #AlexReinking suggests in a comment, you can avoid this warning by giving CMake a (strong) hint regarding which OpenCL location you want to use. Before running CMake, set your OpenCL_ROOT environment variable to /usr/local/cuda; with a CMake version higher than 3.12, the find_package() command will use that variable, preferring to locate OpenCL there if possible - and not warn you about the alternative location.
In CMake version 3.8, native support for CUDA as a language was introduced. When a project has CUDA as one of its languages, CMake will proceed to locate CUDA (e.g. it locates the nvcc binary).
As long as you only compile CUDA code - this is enough. But what if you want to compile a C++ target in that project? The CUDA includes are not -I'ed automatically, and CMakeCache.txt does not seem to contain the CUDA include path anywhere.
Do I actually have to run something find_package(CUDA 9.0 REQUIRED) even when CMake itself has already located CUDA? Or - can I obtain the include directory some other way?
The include directories, which are used by the compiler set by CMAKE_CUDA_COMPILER, can be retrieved from the CMake variable CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.
For getting the libraries, the best way is probably to use find_library() in combination with CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES.
Example:
cmake_minimum_required(VERSION 3.9)
project(MyProject VERSION 1.0)
enable_language(CUDA)
find_library(CUDART_LIBRARY cudart ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
add_executable(
binary_linking_to_cudart
my_cpp_file_using_cudart.cpp
)
target_include_directories(
binary_linking_to_cudart
PRIVATE
${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}
)
target_link_libraries(
binary_linking_to_cudart
${CUDART_LIBRARY}
)
This issue is also discussed on the CMake bug tracker: Provide target libraries for cuda libraries.
Update: CMake 3.17.0 adds FindCUDAToolkit
Instead of doing find_library() manually, the best way as of CMake 3.17.0 would be to use the CUDAToolkit module.
find_package(CUDAToolkit)
add_executable(
binary_linking_to_cudart
my_cpp_file_using_cudart.cpp
)
target_link_libraries(binary_linking_to_cudart PRIVATE CUDA::cudart)
For support with earlier CMake versions, you can ship the CUDATookit module file with minimal changes in your repository.
These days, with CMake 3.18 and later, you can get most of what you need by examining the targets provided by find_package(CUDAToolkit) - which you do need even if CUDA has located the CUDA compiler. But actually, you may just depend on one of those targets and avoid using the include directories directly.
PS - If you happen to use cuda-api-wrappers (e.g. via find_package(cuda-api-wrappers)), it will take care of the dependencies for you.
In CMake version 3.8, native support for CUDA as a language was introduced. When a project has CUDA as one of its languages, CMake will proceed to locate CUDA (e.g. it locates the nvcc binary).
As long as you only compile CUDA code - this is enough. But what if you want to compile a C++ target in that project? The CUDA includes are not -I'ed automatically, and CMakeCache.txt does not seem to contain the CUDA include path anywhere.
Do I actually have to run something find_package(CUDA 9.0 REQUIRED) even when CMake itself has already located CUDA? Or - can I obtain the include directory some other way?
The include directories, which are used by the compiler set by CMAKE_CUDA_COMPILER, can be retrieved from the CMake variable CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.
For getting the libraries, the best way is probably to use find_library() in combination with CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES.
Example:
cmake_minimum_required(VERSION 3.9)
project(MyProject VERSION 1.0)
enable_language(CUDA)
find_library(CUDART_LIBRARY cudart ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
add_executable(
binary_linking_to_cudart
my_cpp_file_using_cudart.cpp
)
target_include_directories(
binary_linking_to_cudart
PRIVATE
${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}
)
target_link_libraries(
binary_linking_to_cudart
${CUDART_LIBRARY}
)
This issue is also discussed on the CMake bug tracker: Provide target libraries for cuda libraries.
Update: CMake 3.17.0 adds FindCUDAToolkit
Instead of doing find_library() manually, the best way as of CMake 3.17.0 would be to use the CUDAToolkit module.
find_package(CUDAToolkit)
add_executable(
binary_linking_to_cudart
my_cpp_file_using_cudart.cpp
)
target_link_libraries(binary_linking_to_cudart PRIVATE CUDA::cudart)
For support with earlier CMake versions, you can ship the CUDATookit module file with minimal changes in your repository.
These days, with CMake 3.18 and later, you can get most of what you need by examining the targets provided by find_package(CUDAToolkit) - which you do need even if CUDA has located the CUDA compiler. But actually, you may just depend on one of those targets and avoid using the include directories directly.
PS - If you happen to use cuda-api-wrappers (e.g. via find_package(cuda-api-wrappers)), it will take care of the dependencies for you.
Hello I need to work with OpenGL and want to create my project in Clion. But Clion cannot compile and run my projects because of the libraries I need to include. I can create my own makefile and run the program in terminal, but I want to do it in the IDE. How can I make this happen?
First make sure you installed all libraries correctly using the compiler you configured in clion/cmake. Assuminf you have a fresh CMakeLists.txt like
cmake_minimum_required(VERSION 3.3.2)
project(MyGL CPP)
add_executable(demo-run main.cpp)
For linking your libraries you need two things. First tell the compiler where to find the include files and second which libraries to link. You could just hard code you local installation like
target_link_libraries(demo-run path/to/glfw.lib path/to/opengl.lib path/to/jpeg.lib ...)
target_include_directories(demo-run PRIVATE path/to/glfw/include path/to/opengl/include path/to/jpeg/include ...)
however this is not very portable and if you want to work with another compiler or on another machine your project file will fail. Instead you can use the package system of cmake
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
find_package(JPEG REQUIRED)
find_package(GLEW REQUIRED)
find_package (OpenGL REQUIRED)
find_package (GLM REQUIRED)
target_link_libraries(demo-run ${GLFW_LIBRARIES} ${GLEW_LIBRARIES} ${JPEG_LIBRARIES} ${OPENGL_LIBRARIES})
target_include_directories(demo-run PRIVATE ${GLFW_INCLUDE_DIRS} ${GLEW_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLM_INCLUDE_DIR})
The glfw part is a bit tricky and works only on linux i guess see http://www.glfw.org/docs/3.0/build.html.
This code is not tested at all and you may need to specify some enviroment variables so cmake can find the packages or provide additional find scripts like https://github.com/lighttransport/nanogi/blob/master/cmake/FindGLM.cmake.
I would recommend to use the CMake build tool which does the work generating Makefiles for you and is also directly supported by clion. When you open the directory containing a CMakeLists.txt (CMake Project File) with clion, it should be automatically be loaded and compiled (if not just hit build)
A very simple example CMake project would look like this
cmake_minimum_required (VERSION 2.8.9)
project (OpenGl-Stuff)
include_directories(src)
add_executable(your-binary src/your-code.c src/your-code.h)
target_link_libraries(your-binary opengl)
# target_link_libraries will search for libopengl on standard system paths,
# maybe the library is not called libopengl, then you have to adjust the name above
this cmake project will generate the binary for you and link it against opengl
I'm learning OpenGL and trying to make my code as portable as possible. For now I managed to compile a project on Ubuntu Linux 14.04, Windows 7 and MacOS. But I having some problems with FreeBSD (PC-BSD 10.2 if that matters). Here is a code example:
https://github.com/afiskon/cpp-opengl-model-view-projection
After running make (see all build steps in README.md) clang complains that it can't find <GL/gl.h> which is used in ./glfw/include/GLFW/glfw3.h. But GL/gl.h is present in /usr/local/include directory.
According to Google this is a well known issue. I tried to manualy edit CMAKE_CXX_FLAGS in CMakeLists.txt, modify environment varibales, etc. Nothing works.
Could you help me, please?
You do find_package(OpenGL REQUIRED) and use ${OPENGL_LIBRARY} (which should be either ${OPENGL_LIBRARIES} or ${OPENGL_gl_LIBRARY} according to documentation), but you don't do include_directories(${OPENGL_INCLUDE_DIR}).
FreeBSD installs all 3d-party software into /usr/local prefix, and many developers assume that all headers they need are within /usr. This is true for Linux just for coincidence. Because of that, if your software uses OpenGL, you should explicitly mention its include and library paths in your build system code and not make assumptions on their location.