C++ 库已链接但引用未定义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7783345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:29:17  来源:igfitidea点击:

library is linked but reference is undefined

c++ubuntulinkeropencl

提问by user615457

I'm trying to compile an openCL program on Ubuntu with an NVIDIA card that worked once before,

我正在尝试使用以前运行过一次的 NVIDIA 卡在 Ubuntu 上编译 openCL 程序,

#include <CL/cl.h>
#include <iostream>
#include <vector>

using namespace std;

int main() {
  cl_platform_id platform;
  cl_device_id device;
  cl_context context;
  cl_command_queue command_queue;
  cl_int error;

  if(clGetPlatformIDs(1, &platform, NULL) != CL_SUCCESS) {
    cout << "platform error" << endl;
  }

  if(clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL) != CL_SUCCESS) {
    cout << "device error" << endl;
  }

  context = clCreateContext(NULL, 1, &device, NULL, NULL, &error);
  if(error != CL_SUCCESS) {
    cout << "context error" << endl;
  }

  command_queue = clCreateCommandQueue(context, device, 0, &error);
  if(error != CL_SUCCESS) {
    cout << "command queue error" << endl;
  }

  return 0;
}

I compile it like so,

我是这样编译的

g++ -I/usr/local/cuda/include -L/usr/lib/nvidia-current -lOpenCL opencl.cpp

and I get this result

我得到了这个结果

/tmp/ccAdS9ig.o: In function `main':
opencl.cpp:(.text+0x1a): undefined reference to `clGetPlatformIDs'
opencl.cpp:(.text+0x3d): undefined reference to `clGetDeviceIDs'
opencl.cpp:(.text+0x65): undefined reference to `clCreateContext'
opencl.cpp:(.text+0x85): undefined reference to `clCreateCommandQueue'
collect2: ld returned 1 exit status

but nm -D /usr/lib/nvidia-current/libOpenCL.sotells me that libOpenCL.so at least contains clGetPlatformIDs

nm -D /usr/lib/nvidia-current/libOpenCL.so告诉我 libOpenCL.so 至少包含 clGetPlatformIDs

0000000000002400 T clGetKernelWorkGroupInfo
0000000000002140 T clGetMemObjectInfo
0000000000002e80 T clGetPlatformIDs
0000000000002de0 T clGetPlatformInfo
0000000000002310 T clGetProgramBuildInfo
00000000000022f0 T clGetProgramInfo
00000000000021f0 T clGetSamplerInfo

Am I missing something.

我是不是错过了什么。

采纳答案by Geoffroy

From the gccman page:

gcc手册页:

   -llibrary
   -l library
       Search the library named library when linking.  (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)

       It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified.  Thus, foo.o
       -lz bar.o searches library z after file foo.o but before bar.o.  If bar.o refers to functions in z, those functions may not be loaded.

       The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a.  The linker then uses this file as if it had been specified
       precisely by name.

So try to specify the -lOpenCLafter the file argument in your compile command.

因此,请尝试-lOpenCL在编译命令中指定文件参数之后的后面。

You also search for symbols in libOpenCL.so, which is a shared library file. With your command you link your program agains a static library, in the format libOpenCL.a.

您还可以在 libOpenCL.so 中搜索符号,这是一个共享库文件。使用您的命令,您可以将程序再次链接到静态库,格式为libOpenCL.a.

回答by user615457

when you are linking, the order of your libraries and source files makes a difference. for example for your case,

链接时,库和源文件的顺序会有所不同。例如对于你的情况,

g++ -I/usr/local/cuda/include -L/usr/lib/nvidia-current -lOpenCL opencl.cpp

g++ -I/usr/local/cuda/include -L/usr/lib/nvidia-current -lOpenCL opencl.cpp

functions defined in the OpenCL library might not be loaded, since there nothing before them asking for a look-up. however if you use,

OpenCL 库中定义的函数可能不会被加载,因为在它们之前没有任何东西要求查找。但是,如果您使用,

g++ opencl.cpp -I/usr/local/cuda/include -L/usr/lib/nvidia-current -lOpenCL  

then any requests for functions will be found in the OpenCL library and they will be loaded.

然后将在 OpenCL 库中找到任何对函数的请求并加载它们。

回答by Jesse

Alternatively you can add the header and library path to your global variables.

或者,您可以将标头和库路径添加到全局变量中。

export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/local/cuda/include
export LIBRARY_PATH=$LIBRARY_PATH:/usr/lib/nvidia-current

You can also try to set

您也可以尝试设置

export PATH=$PATH:/usr/local/cuda/bin

It should be possible to run now

现在应该可以运行了

g++ opencl.cpp