CUDA compilation with relocatable code: "Could not find fatbin in ..." - cmake

As part of a larger CMake project, I am adding a CUDA library. The rest of the project is C++, compiled with clang.
To test that the library works correctly, I'm creating a small executable and linking the CUDA library to it:
add_library(kernels STATIC
kernels.cu
)
set_target_properties(kernels PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
# --- Test executable
add_executable(main
main.cpp
)
target_link_libraries(main PRIVATE kernels)
The library compiles fine, but I get the following error when nvcc is invoked to do the device linking part of the process on my executable (target main):
nvlink fatal : Could not find fatbin in '[some long path]/main.cpp.o'
nvlink fatal : elfLink internal error
What is preventing this step from working?

I couldn't reproduce this issue in a fresh, tiny CMake project, so I eventually figured out that some flag from my larger project wasn't playing along.
It turns out that Thin LTO, which was enabled in CMAKE_CXX_FLAGS is causing this issue.
I disabled it for this particular target with:
target_compile_options(main PRIVATE "-fno-lto")

Related

install targets after pybind11_add_module in cmake and Yocto

I am trying to use python to interfacing my own c++ library. Actually I can do it manually copying pybind11_example.so to the target device. I hope to do this by using install(TARGETS...
I found this link. But it doesn't help in my Yocto build.
This is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.14.4)
project(pybind11_example)
set(CMAKE_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../lib/math/include")
find_package(PythonLibs REQUIRED)
set(PYTHON_MODULE_EXTENSION ".so" CACHE INTERNAL "Cross python lib extension")
find_package(pybind11 REQUIRED)
pybind11_add_module(${PROJECT_NAME} pybind11_wrapper.cpp)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_INCLUDE_PATH})
target_link_libraries(${PROJECT_NAME} PRIVATE simplemath)
include(GNUInstallDirs)
# without lines below, yocto build works fine
install(TARGETS ${PROJECT_NAME}
COMPONENT python
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
This is the error from devtool build:
ERROR: pybind11-example-1.0+git999-r0 do_package: QA Issue: pybind11-example: Files/directories were installed but not shipped in any package:
/usr/lib/pybind11_example.so
Please set FILES such that these items are packaged. Alternatively if they are unneeded, avoid installing them or delete them within do_install.
pybind11-example: 1 installed and not shipped files. [installed-vs-shipped]
ERROR: pybind11-example-1.0+git999-r0 do_package: Fatal QA errors found, failing task.
Oops, I found the reason. The problem was not in cmake but in .bb file.
After I add FILES_${PN} += "/usr/lib" in the .bb, it works fine.
For more detail, please see this link.

How to solve the problem that clion keeps processing?

when i try to modify my CMakeLists or compile a project, it gives the warning: processing ( Code analysis has been suspended. Heavy operation is running. ) Then I cannot compile my project.
The version of clion is 2021.3.2. And the cmake_minimum_required is version 3.21
cmake_minimum_required(VERSION 3.21)
The clion project occupy huge part of the CPU.
The project I want to compile is simple just like this:
#include <stdio.h>
int main(){
printf("hello2!");
return 0;}
The Cmakelists is properly written:
cmake_minimum_required(VERSION 3.21)
project(test C)
add_executable(test
hello2.c)
I try to compile the project in Linux and it success. (Ubuntu 20.04 VMware Workstation) . But it always fail in Windows.
enter image description here
Also, the project can be compiled successfully when I open it at first without doing any changes. After I do some simple changes, it shows processing and fails to compile. But I can save these changes and open it as a clion project to enable it to compile.
This question was solved. I changed my regedit by mistake for some reasons. After I reinstall the system(windows10). This problem disappear.

Building a rust library through CMake and using it as imported library target

I'm restucturing the CMake based build of a cross platform (macOS/Windows, Linux should be added soon) C++ project that has a third party rust library as dependendcy. Until now the rust lib dependency was supplied as precompiled library but I want to make its compilation part of my CMake build.
I got it working on macOS using the CMake makefile exporter by referencing the compiled library as a static imported library target and setting up a custom target with the command to build the rust library through cargo like this
add_library (rustlib STATIC IMPORTED)
add_custom_target (rustlib_cargo
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/Ext/rustlib/c-api
COMMAND cargo rustc --release -- --crate-type staticlib)
# Note: RUSTLIB_OUTPUT is set above refering to the absolute path of the produced platform specific library
set_target_properties (rustlib PROPERTIES IMPORTED_LOCATION ${RUSTLIB_OUTPUT})
add_dependencies (rustlib rustlib_cargo)
On macOS the cargo rustc command is invoked before the targets that link against my rustlib target are built and in case the rust library has been built previously this is detected by cargo and it just skips that compilation steph. But on Windows this fails with the built-in ninja exporter of Microsoft Visual Studio 2019 with an error like this:
ninja : error : '../../../Ext/rustlib/target/release/deps/rustlib.lib', needed by 'SomeTargetLinkingAgainstRustlib', missing and no known rule to make it
If I remove the line set_target_properties (rustlib PROPERTIES IMPORTED_LOCATION ${RUSTLIB_OUTPUT}) the build starts correctly, the rust build gets triggered, but as expected I end up with a linker error as the library to link against is not found. So is there any way to refer to a file that is not existent at configuration time but is guranteed to be created during compilation?

Cmake cannot find wxWidgets on Windows

I have searched for this topic and found this and this, but it only seems to either pertain to building wxWidgets or do not contain an answer to my question.
I have built the static libs für wxWidgets on Windows successfully, but I am now struggling to correctly include the libraries to my project using Cmake. This is my CMakeLists.txt:
set(PROJECT_NAME wxapp)
project(${PROJECT_NAME})
cmake_minimum_required(VERSION 2.8)
set(SRC_LIST main.cpp app.cpp app.h frame.cpp frame.h)
add_executable(${PROJECT_NAME} WIN32 ${SRC_LIST})
find_package(wxWidgets REQUIRED net gl core base)
include(${wxWidgets_USE_FILE})
target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES})
set(wxWidgets_USE_LIBS ON)
set(wxWidgets_CONFIGURATION msw)
I have set the WXWIN path variable correctly. Yet, CMake throws an error with this configuration:
Could NOT find wxWidgets (missing: wxWidgets_LIBRARIES
wxWidgets_INCLUDE_DIRS net gl core base)
I have tried multiple suggestions, like using downloading prebuild dynamic libraries and adding them manually as suggested here, e.g.
set(wxWidgets_ROOT_DIR $ENV{WXWIN})
set(wxWidgets_LIBRARIES $ENV{WXWIN}/include)
set(wxWidgets_INCLUDE_DIR $ENV{WXWIN}/lib/vc14x_x64_dll)
include_directories(includes $ENV{WXWIN} $ENV{WXWIN}/include $ENV{WXWIN}/lib/vc14x_x64_dll)
link_directories($ENV{WXWIN} $ENV{WXWIN}/include $ENV{WXWIN}/lib/vc14x_x64_dll) # this seems to be a discouraged/deprecated method
but all to no avail.
WORKAROUND (at least it works for me):
I changed the find_package command from the suggested statement:
find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net)
to
find_package(wxWidgets 3.1 REQUIRED)
A user in this post had this included in his/her CMake file and out of deperation, I tried this and it actually worked. Seems like the configuration of CMake under certain unknown circumstances won't function correctly with the statement provided in the instructions. If I change the command to the new statement my static build as well as self- and precompiled dlls are flawlessly identifed by CMake.
I also cleared the CMake cache, inspired by this post. According to this post, there seems to be an issue with Windows and the CMake cache in some situations, but the reasons escape me. I could replicate the behaviour observed by the user there:
Under Windows, you have to point to the installation directory, e.g.
set(wxWidgets_ROOT_DIR "C:/wxWidgets-3.1.3") set(wxWidgets_LIB_DIR
"C:/wxWidgets-3.1.3/lib/vc14x_x64_dll")
But then the behavior is still strange. When i use CMake GUI (3.16,
latest), behavior is like this
delete cache (just to be consistent)
press 'configure' button
--> fail: CMake Error at C:/Program Files/CMake/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:146
(message): Could NOT find wxWidgets (missing: wxWidgets_LIBRARIES
wxWidgets_INCLUDE_DIRS core base qa adv net html gl propgrid richtext)
press 'configure' button again
--> success
I also have observed some inconsistent behaviour of CMake within the IDEs CLion and CodeBlocks when clearing the cache and reloading the project.
So, exactly how the cache clearing plays into the resolution of my issue, I don't know. But if I merely clear the cache, reload my project and leave the CMake instruction at find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net), CMake won't find my installation despite the WXWIN path being set correctly.
If you know more about this, I am happy to be corrected.

Force cmake to re-run CHECK_CXX_SOURCE_COMPILES after external libraries have been set up

Using CMake I want to check if a particular function (cv::getGaborKernel) from OpenCV library is available (it is available only in quite recent version of the library). If it is, I will use it in my code, if it is not, I redefine it in my code, in btw #ifdefs.
Here is a snippet of my CMakeLists.txt:
FIND_PACKAGE(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
set(CMAKE_REQUIRED_INCLUDES ${OpenCV_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${OpenCV_LIBS})
INCLUDE(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES(
"
#include <opencv2/imgproc/imgproc.hpp>
int
main()
{
cv::Mat toto = cv::getGaborKernel(cv::Size(11,11), 1,0,3,1,0, CV_64F);
}
" HAVE_OPENCV_GABOR)
if(HAVE_OPENCV_GABOR)
message("Using OpenCV Gabor implementation")
else(HAVE_OPENCV_GABOR)
message("Using custom Gabor implementation")
endif(HAVE_OPENCV_GABOR)
When deploying on a computer with recent OpenCV version (which does have cv::getGaborKernel), the test fails, forcing the redefinition of the function and some compilation errors.
The problem reside in the fact that OpenCV not beeing installed in standard directory, it first fails to locate the library. So the sample program cannot be built. However, after I properly set up OpenCV dependencies, the test for HAVE_OPENCV_GABOR is not run again as the failure is registered in the cache.
How can I force CMake to rerun the test in that case?
Just wrap your CHECK_CXX_SOURCE_COMPILES() call with
if(NOT OpenCV_INCLUDE_DIRS OR NOT OpenCV_LIBS)
...
endif()
Another solution - add unset(HAVE_OPENCV_GABOR CACHE) before running CHECK_CXX_SOURCE_COMPILES().