cmake真心強大,這不,我這有個Makefile管理的CUDA項目需要大改,程序目錄結構替換,可能導致大量的Makefile工程文件需要維護,我想着cmake可不可以編譯CUDA項目呢,果然沒有讓人失望。
FIND_PACKAGE(CUDA REQUIRED)
cuda_add_library(... ...)
cuda_add_executable(... ...)
一如既往的簡單,不過,總有讓人氣餒的地方:
~/project_tst/src/compute/cuda/ckernels.cu(52): error: identifier "BLOCK" is undefined
1 error detected in the compilation of "/tmp/tmpxft_00000706_00000000-6_ckernels.cpp1.ii".
CMake Error at vas_generated_ckernels.cu.o.cmake:280 (message):
Error generating file
~/project_tst/build/CMakeFiles/vas.dir/src/compute/cuda/./test_generated_ckernels.cu.o
CMakeFiles/vas.dir/build.make:740: recipe for target 'CMakeFiles/vas.dir/src/compute/cuda/vas_generated_ckernels.cu.o' failed
make[2]: *** [CMakeFiles/vas.dir/src/compute/cuda/test_generated_ckernels.cu.o] Error 1
make[2]: *** Waiting for unfinished jobs....
~/project_tst/src/compute/cuda/ckernels.cu(185): error: identifier "cuda_random" is undefined
~/project_tst/src/compute/cuda/ckernels.cu(198): error: identifier "cuda_gridsize" is undefined
~/project_tst/src/compute/cuda/ckernels.cu(199): error: identifier "check_error" is undefined
3 errors detected in the compilation of "/tmp/tmpxft_0000073c_00000000-6_crop_layer_kernels.cpp1.ii".
上面介紹,可能很多小夥伴看着恐懼,其實就是 “BLOCK” 宏定義找不到。這個就莫名其妙了,項目也構成成功了,頭文件也找到了,宏定義是我的項目裏面大大的顯示起的。
但也沒必要慌,問題總是要解決的,我們來跟蹤下。
make VERBOSE=1
恩恩,這裏就可以顯示出來項目編譯時候的命令了
/usr/local/cuda/bin/nvcc \
~/project_tst/src/compute/cuda/ckernels.cu \
-c \
-o ~/project_tst/build/CMakeFiles/test.dir/src/compute/cuda/./test_generated_ckernels.cu.o \
-ccbin /usr/bin/cc \
-m64 \
-DGPU \
-DCUDNN \
-gencode \
arch=compute_61,code=sm_61 -std=c++11 -DNVCC \
-I/usr/local/cuda/include \
-I~/project_tst/src/compute/inc \
-I~/project_tst/include
這命令說明問題大致運行是沒有毛病的,這就讓我摸不到頭腦了。我直接把命令放到命令行裏面運行,發現還真的有問題。
千般調戲,額,調試,果然是小問題,看到倒數第三行的-I/usr/local/cuda/include
,如果沒有這一行的話,就沒問題了。
問題我大概定位在因爲我工程裏的頭文件名和cuda提供的文件衝突了,折騰,cuda的頭文件命名和我一樣隨便,它還是啥世界通用的加速項目,吐吐槽,哈哈。
又說回來,這個cuda尋找目錄不指明,項目其他部分編譯又有問題,爲啥以前在Makefile做的時候沒有發現呢。於是我把頭文件查找順序替換了一下,發現問題也沒有了。
好嘛,問題定位沒問了,我們來看看怎麼解決。
這個cuda目錄沒有手動添加,只能是cmake後面做了手腳,那就還得看看cmake怎麼說,官網來了。
官網說了,之所以編譯的時候有這個cuda的目錄是因爲 包含 這個cuda目錄的 CUDA_INCLUDE_DIRS 變量 被工程默認引用了。
我只是想替換下順序,怎麼做到呢,我這裏提供一種"愚蠢"的方法,供大家參考:
set(prj_name test)
set(prj_src ${test_src})
set(prj_inc ${test_inc} include)
set(prj_def PUBLIC GPU=1 PUBLIC CUDNN=1)
# 將CUDA_INCLUDE_DIRS變量中的值保存到另外一個變量中
set(cuda_inc ${CUDA_INCLUDE_DIRS})
# 把 CUDA_INCLUDE_DIRS 變量值空
set(CUDA_INCLUDE_DIRS)
cuda_add_library(${prj_name} SHARED ${prj_src})
target_compile_definitions(${prj_name} ${prj_def})
# 這裏通過我們的自定義變量就可以自定義引用順序了
target_include_directories(${prj_name} ${prj_inc} ${cuda_inc})
坑真大,不過還是一臉灰的出來了。供大家參考!!