LINUX.ORG.RU

Перевожу проектик на cmake

 ,


1

1

Есть небольшой проектик совсем... так, малюсенький. Написан на C++ с использованием CUDA

Структура такая:

./include/cube.h
./include/integrate.h
./src/cpuintegrate.cpp
./src/cuintegrate.cu
./src/cube.cpp
./src/main.cpp

Использовал он довольно криво написанный Makefile, что меня конечно же не радовало. Мне нужно, например, будет в будущем добавить помимо main.cpp других файлов, которые будут исполнимыми и содержать функцию main, и которые будут использовать те же библиотечные файлы... вот так как-то.

В общем, настряпал я вот такой CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(GpuDensity)
FIND_PACKAGE(CUDA)

set(LINK_FLAGS "-lcurand -lgsl")

INCLUDE_DIRECTORIES(
"include/"
"src/"
"/opt/cuda/include"
)

CUDA_ADD_LIBRARY(cube "src/cube.cpp")
CUDA_ADD_LIBRARY(cpuintegrate "src/cpuintegrate.cpp")
CUDA_ADD_LIBRARY(cuintegrate "src/cuintegrate.cu")

CUDA_ADD_EXECUTABLE(main "src/main.cpp" "include/cube.h" "include/integrate.h")

TARGET_LINK_LIBRARIES(main cube)
TARGET_LINK_LIBRARIES(main cpuintegrate)
TARGET_LINK_LIBRARIES(main cuintegrate)

вроде бы все зависимости указал правильно... надеюсь. cmake отрабатывает нормально, а вот make выводит вот такую ошибку:

libcpuintegrate.a(cpuintegrate.cpp.o): In function `next(gsl_rng const*, float, float)':
cpuintegrate.cpp:(.text+0x56): undefined reference to `gsl_rng_uniform'
libcpuintegrate.a(cpuintegrate.cpp.o): In function `uniform(int, double, double)':
cpuintegrate.cpp:(.text+0x8f): undefined reference to `gsl_rng_default'
cpuintegrate.cpp:(.text+0x97): undefined reference to `gsl_rng_alloc'
cpuintegrate.cpp:(.text+0xad): undefined reference to `gsl_rng_set'
libcuintegrate.a(cuintegrate_generated_cuintegrate.cu.o): In function `cuintegrate(task_t)':
....
тут много раз что-то вроде:
cuintegrate.cu:142: undefined reference to `curandCreateGenerator'
....
collect2: выполнение ld завершилось с кодом возврата 1
make[2]: *** [main] Ошибка 1
make[1]: *** [CMakeFiles/main.dir/all] Ошибка 2
make: *** [all] Ошибка 2

Такая ошибка возникает, если не добавлять флаги к компилятору, которые мне нужны - это -lcurand и -lgsl (первый для библиотеки curand из cuda, второй для библиотеки GSL).. Вот. Переменную я такую вроде бы указал set(LINK_FLAGS "-lcurand -lgsl"), но он её не подхватывает.... может. я что-то неправильно сделал?

★★★★★

Последнее исправление: BattleCoder (всего исправлений: 1)

И ещё вдогонку вопрос - хотелось бы явно не указывать include/header.h и src/module.cpp в cmake... хотелось бы как-нибудь указать include-dir и src-dir, чтобы он всё так делал..

а бинарник запихивал бы bin/

BattleCoder ★★★★★
() автор топика

Почитайте документацию, много вопросов просто отпадут сами собой:

хотелось бы как-нибудь указать include-dir

http://cmake.org/cmake/help/v2.8.8/cmake.html#command:include_directories

make VERBOSE=1 - посмотрите, какие флаги компиляции/линковки. Возможно тащатся статические библиотеки.

kulti ★★
()

Переменную я такую вроде бы указал set(LINK_FLAGS "-lcurand -lgsl"), но он её не подхватывает.... может. я что-то неправильно сделал?

Все библиотеки надо указывать в TARGET_LINK_LIBRARIES:

TARGET_LINK_LIBRARIES(main cube cpuintegrate cuintegrate curand gsl)
Begemoth ★★★★★
()
Ответ на: комментарий от kulti

Сдаётся мне это не совсем то, что мне нужно... Документацию изучаю. :) только, млин, сложный этот cmake и запутанный. Хотя уже оценил его плюсы по сравнению с обычным make.

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от Begemoth

Да, действительно. Спасибо. :) Помогло, только не до конца...

gsl он без проблем находит, а вот curand не хочет. Находится эта библиотека в /opt/cuda/lib, вот если ему это как-то указать...

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от Begemoth
/usr/lib/gcc/i686-pc-linux-gnu/4.5.3/../../../../i686-pc-linux-gnu/bin/ld: cannot find -lcurand

Вот такое вот пишет...

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от Begemoth

Собственно, проблема в том, что он пытается использовать g++ вместо nvcc, хотя должен бы использовать nvcc..

Вот я пробую вручную

g++ main.o cu.o cpu.o cube.o -o main -lcurand -lgsl
/usr/lib/gcc/i686-pc-linux-gnu/4.5.3/../../../../i686-pc-linux-gnu/bin/ld: cannot find -lcurand
collect2: выполнение ld завершилось с кодом возврата 1

В то время как

nvcc main.o cu.o cpu.o cube.o -o main -lcurand -lgsl

Отрабатывает без ошибок.

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от unC0Rr

Почему-то не помогло. И если указать такую переменную для make - тоже не помогает.

Вот какой получается MakeFile:

https://github.com/kozlov-p-v/gpucomputes/blob/master/gpudensity/Makefile

Ну и все остальные файлы проекта там же https://github.com/kozlov-p-v/gpucomputes/blob/master/gpudensity

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от kulti

Добавил строку

set (CMAKE_CXX_COMPILER nvcc)
И вижу
nvcc fatal   : Unknown option 'rdynamic'
Час от часу не легче. :( Интересно, зачем ему нужна эта опция и как бы без неё обойтись?

P.S. А я то думал, cmake мне всё облегчит и cuda сама подхватится, на то и findCUDA. Так нет же! Наоборот одни проблемы.

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от kulti

Я вот одного не могу понять. Почему не прокатывает

LD_LIBRARY_PATH="/opt/cuda/lib" make
??? должно же... хотя это и грязный хак, но должен работать.

А как это сделать «правильно», я пока так и не понял.

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от kulti

запустил make VERBOSE=1, теперь хоть понятно стало, какую команду он вводит:

/usr/bin/c++       CMakeFiles/main.dir/src/main.cpp.o  -o main -rdynamic libcube.a libcpuintegrate.a libcuintegrate.a -lgsl -lcurand /opt/cuda/lib/libcudart.so -lcuda -Wl,-rpath,/opt/cuda/lib 
И вот на неё ругается что не может найти -lcurand

В то время как вот такая вот команда 100% рабочая (руками вводил)

g++ -o main CMakeFiles/main.dir/src/main.cpp.o CMakeFiles/cpuintegrate.dir/src/cpuintegrate.cpp.o CMakeFiles/cuintegrate.dir/src/cuintegrate_generated_cuintegrate.cu.o CMakeFiles/cube.dir/src/cube.cpp.o -L/opt/cuda/lib -lcudart -lcurand -lgsl

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от kulti

Хотя, я наверно не совсем прав. Мое предложение - костыль, но я никогда с cuda не работал и предложил первое, что в голову пришло.

Вот тут немного по другому делают, нежели вы пытались: http://rafaelpalomar.net/blog/2010/jan/22/building-cuda-projects-cmake

kulti ★★
()
Ответ на: комментарий от kulti

что-то мне не нравится этот вариант... мне надо чтобы я cmake запускал без всяких параметров... чтобы этот тулчейн был по умолчанию %)

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от kulti

Там не используется внешняя библиотека (в моём случае libcurand.so). И там такой проблемы не возникает....

без неё у меня всё работает отлично... но мне она нужна :( и может ещё libcublas/libcufft могут понадобиться потом

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от BattleCoder

Для путей к библиотекам link_directories.

Но, как я написал в посте выше, с Cuda не работал. Но судя по всему в cmake есть для этого много полезного. Да получается cmake немного сложнее helloworld-ного =) В общем, тут как с Qt, нужно взять реальный проект его использующий, либо нагуглить что-нибудь, как в приведенной ссылке в посте выше.

Удачи

kulti ★★
()
Ответ на: комментарий от kulti

А не... спасибо. помогло. там чуть ниже есть рецепт!!! Огромный пряник вам. почему сразу не догадался..

Одного так и не пойму, почему мои «костыли» до этого не помогали... надо осваивать этот cmake до конца.

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от kulti
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(GpuDensity)
FIND_PACKAGE(CUDA)

find_library(CURAND_LIBRARY curand "/opt/cuda/lib")

INCLUDE_DIRECTORIES(
"include/"
"src/"
)

CUDA_ADD_LIBRARY(cube "src/cube.cpp")
CUDA_ADD_LIBRARY(cpuintegrate "src/cpuintegrate.cpp")
CUDA_ADD_LIBRARY(cuintegrate "src/cuintegrate.cu")

ADD_EXECUTABLE(main ${CUDA_FILES} "src/main.cpp" "include/cube.h" "include/integrate.h")

TARGET_LINK_LIBRARIES(main cube cpuintegrate cuintegrate gsl curand)

В общем вот финальный cmakelists который получился. Теперь без проблем смогу добавить новые executable (это и была основная цель, одного main мне тут мало)

Спасибо! :) проблема решена.

BattleCoder ★★★★★
() автор топика
23 сентября 2012 г.

Никто не подскажет, в чём может быть дело? CMakeLists.txt такой же, я его не менял... но после обновления до CUDA-5 он валится с такой вот ошибкой:

-- Could NOT find CUDA (missing: CUDA_INCLUDE_DIRS) (found version «5.0»)

CMake Error: The following variables are used in this project, but they are set to NOTFOUND.

BattleCoder ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.