如何阻止 cmake 尝试 link 针对不存在的库?

How to stop cmake from trying to link against non-existing library?

如果这是一个天真的问题,我很抱歉,因为我对 CMake 总体上很不熟悉。

我正在尝试编译一个非常大的开源软件项目 (OpenCV)。我似乎已经使用以下命令行参数将所需的大多数库获取到路径中。

-DCUDNN_INCLUDE_DIR='${CONDA_PREFIX}/include' \
-DCUDNN_LIBRARY='/${CONDA_PREFIX}/lib' \
-DC_INCLUDE_PATH=${CONDA_PREFIX}/include:/usr/local/include:/usr/include/x86_64-linux-gnu: \
-DINCLUDE_PATH=${CONDA_PREFIX}/include:/usr/local/include:/usr/include/x86_64-linux-gnu \
-DC_PATH=${CONDA_PREFIX}/include:/usr/local/include:/usr/include/x86_64-linux-gnu \
-DLD_LIBARY_PATH=${CONDA_PREFIX}/lib:/usr/lib/x86_64-linux-gnu \

确实,CMake 能够找到它需要的库,如 CUDA、CuDNN、OpenBlas、FFMpeg 等。暂时一切似乎都很顺利。

然而,在链接阶段,CMake 一直附加一个奇怪的库引用“-llib”。当然,lib 是一个不存在的库。例如,这样的命令之一是

cd /home/albert/app/src/opencv/build/modules/cudev && /usr/bin/cmake -E cmake_link_script CMakeFiles/opencv_cudev.dir/link.txt --verbose=1

/usr/bin/c++ -fPIC -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Winit-self -Wpointer-arith -Wsign-promo -Wuninitialized -Winit-self -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -Wno-undef -Wno-missing-declarations -Wno-unused-function -Wno-unused-variable -Wno-enum-compare -Wno-shadow -O3 -DNDEBUG -DNDEBUG -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a -Wl,--gc-sections -Wl,--as-needed -shared -Wl,-soname,libopencv_cudev.so.4.4 -o ../../lib/libopencv_cudev.so.4.4.0 CMakeFiles/opencv_cudev.dir/src/stub.cpp.o -L/usr/local/cuda/lib64 -L/home/albert/.conda/envs/denseflow -Wl,-rpath,/usr/local/cuda/lib64:/home/albert/.conda/envs/denseflow::::::::::::::::::::::: -ldl -lm -lpthread -lrt ../../3rdparty/lib/libippiw.a ../../3rdparty/ippicv/ippicv_lnx/icv/lib/intel64/libippicv.a -lcudart_static -lpthread -ldl -lrt -lnppc -lnppial -lnppicc -lnppidei -lnppif -lnppig -lnppim -lnppist -lnppisu -lnppitc -lnpps -lcublas -llib -lcufft -L/usr/local/cuda/lib64 -L/usr/lib/x86_64-linux-gnu -L/home/albert/.conda/envs/denseflow -lcudart_static -lpthread -ldl -lrt -lnppc -lnppial -lnppicc -lnppidei -lnppif -lnppig -lnppim -lnppist -lnppisu -lnppitc -lnpps -lm -lpthread -lcublas -llib -lcufft

这会导致以下错误。

/usr/bin/ld: cannot find -llib collect2: error: ld returned 1 exit status make[2]: *** [modules/cudev/CMakeFiles/opencv_cudev.dir/build.make:89: lib/libopencv_cudev.so.4.4.0] Error 1

如果我从 C++ 命令中手动删除“-llib”(两次出现),命令将成功执行。

这里发生了什么?

虽然我不熟悉CMake,但感觉应该有一个简单的方法来防止CMake这样做。

非常感谢您的帮助。

更新: OpenCV CMake 文件似乎有问题。当我 运行 CMake 时,它​​的输出之一是

-- Extra dependencies: dl m pthread rt cudart nppc nppial nppicc nppidei nppif nppig nppim nppist nppisu nppitc npps cublas lib cufft -L/usr/local/cuda-11.6/lib64 -L/home/albert/.conda/envs/denseflow

这里已经出现神秘库

网上有人建议手动修改 CMakeCache.txt,但我无法让它工作。 CMake 只是在我修改后覆盖它。

问题是由以下CMake选项引起的。

-DCUDNN_LIBRARY='/${CONDA_PREFIX}/lib'

删除这个选项解决了这个问题。看起来这个路径应该是一个文件,而不是一个目录。我不确定它应该指向 CUDA 11.6 和 CuDNN 8.3.2 的哪个文件,但只需删除这一行就足够了。

它应该指向cudnn lib文件。在 Mac 上使用这个

-DCUDNN_LIBRARY=/usr/local/cuda/lib/libcudnn.dylib