【问题标题】:[C]undefined reference while compiling openCL program[C]编译openCL程序时未定义的引用
【发布时间】:2011-06-15 22:18:27
【问题描述】:

我正在尝试编译一些东西来试用 openCl,但我遇到了一些问题..

这里是代码

prova.c

#include <stdio.h>
#include <CL/opencl.h>
#include "Utils\util.h"
#include <malloc.h>

int main(){
    cl_int error = 0;   // Used to handle error codes
    cl_int max_platforms = 1; // The maximum number of platforms
    cl_uint adviable_platforms = 0; //The adviable number of platforms
    cl_platform_id* platform;

    error = clGetPlatformIDs(0, NULL, &adviable_platforms);
    if(adviable_platforms == 0)
    {
        printf("No adviable platforms.\n");
        return -1;
    } else {
        platform = (cl_platform_id*)malloc(adviable_platforms * sizeof(cl_platform_id));
    }

    error = clGetPlatformIDs(adviable_platforms, platform, NULL);


    printf("clGetPlatformIDs: %s\n", clErrorString(error));
    return 0;
}

我正在使用 mingw32 在 win 7 64 上进行编译。 opencl 头文件位于 mingw 的 include 目录中,而 utils.h(在 prova.c 目录中的 Utils 目录中)定义了 clErrorString(简单地将错误转换为更易于阅读的字符串)。

编译我使用

gcc -L\Utils prova.c

但我总是得到

C:\[stuff]\ccEjYQbj.o:prova.c:(.text+0x42): undefined reference to 'clGetPlatformIDs@12'
C:\[stuff]\ccEjYQbj.o:prova.c:(.text+0x8d): undefined reference to 'clGetPlatformIDs@12'
C:\[stuff]\ccEjYQbj.o:prova.c:(.text+0x9e): undefined reference to 'clErrorString'

我不太擅长编译器,所以我想我错过了一些东西,但我真的不知道是什么..

编辑: 真诚地,我尝试了我想到的每一个命令。使用 -L 包含目录,使用 -l 链接到文件,使用 ar..

这是我尝试的最后一个“脚本”

set PATH=%PATH%;C:\Python26;C:\MinGW\bin;C:\MinGW\lib

cd Utils
gcc -c util.c -l"C:\Program Files (x86)\AMD APP\lib\x86_64\libOpenCL.a" -o util.o
ar rcs libutil.a util.o

cd..
pause

gcc -c prova.c -l"Utils\libutil.a" -o prova.exe

pause

EDIT2:

@echo off
set PATH=%PATH%;C:\Python26;C:\MinGW\bin;C:\MinGW\lib

cd Utils
gcc -Wall -c util.c -L"C:\Program Files (x86)\AMD APP\lib\x86_64\" -o util.o
ar rcs libutil.a util.o

cd..
pause

gcc -Wall -c prova.c -L"C:\Program Files (x86)\AMD APP\lib\x86_64\" -l"Utils\libutil.a" -o prova.exe

pause

没有错误,唯一的警告是 max_platform 未使用。然后我在 Utils 和 prova.o(size 1kb) 中找到了 util.o 和 libutil.a(size 5kb)。如果我尝试运行 prova.o,它说文件版本与当前的 windows 版本不兼容,请检查系统版本(x86 或 x64)并联系软件经销商

【问题讨论】:

  • 这是一个链接器错误,而不是编译器错误。您需要在 OpenCL 库中进行链接。
  • 查看 mingw "lib" 目录,看看是否可以找到某种 CL 库(可能是名为 "libcl*.a" 的东西)。然后通过“-l”将名称(减去“lib”和“.a”)传递给编译器。
  • @Makers_F:你确定你的最后一条命令吗? -l 采用库名称,而不是目录,你在想-L 吗?而且您仍然没有链接到 opencl 库。
  • @Makers:如果您的最后一行指示正确的相对位置,请尝试gcc -c prova.c "Utils\libutil.a" -o prova.exe。您不需要将-l 用于静态库,您只需像普通目标文件一样指定它们。 (如果你说-lname,链接器会查找文件libname.alibname.so。)
  • @Makers_F:“它没有链接”是什么意思?您是否收到任何错误,以及来自哪个程序?也许您可以发布您执行的操作的更详细的输出?

标签: c include compilation opencl


【解决方案1】:

试试这样的:

set PATH=%PATH%;C:\Python26;C:\MinGW\bin;C:\MinGW\lib

cd Utils
gcc -W -Wall -c util.c -o util.o
ar rcs libutil.a util.o

cd..

gcc -W -Wall -c prova.c -o prova.o
gcc -o prova.exe prova.o Utils\libutil.a

# Using a standard library
gcc -o prog.exe myprog.o -lzip  # e.g. /usr/lib/libz.a

# Using a nonstandard library
gcc -o prog.exe myprog.o -lfoo -L/tmp/libfoo  # uses /tmp/libfoo/libfoo.a
gcc -o prog.exe myprog.o /tmp/libfoo/libfoo.a # same effect

一般:

  • 使用 -c:
    gcc -c myfile.c -o myfile.o 编译单个源文件。
    这将创建 object 文件。

  • 将所有对象文件链接到可执行文件(或共享库):
    gcc -o prog.exe myfile.o yourstuff.o sha257.o

  • 您可以将目标文件合并到一个静态库中,在链接时将其视为单个目标文件:
    ar rcs libcoolstuff.a yourstuff.o sha257.o
    gcc -o prog.exe myfile.o libcoolstuff.a
    或者:gcc -o prog.exe myfile.o -lcoolstuff
    后一种语法(使用-l 自动链接库)需要在库路径中找到libcoolstuff.alibcoolstuff.so(您可以在链接时使用-L 进行修改)。

【讨论】:

  • 非常好的解释!!有了这个我设法编译了一个非常简单的项目(我写来测试它),其中包括一个源,包括另一个源,我设法编译并链接它们。比我尝试使用 openCL 程序。编译进行得很好,但是在链接时我得到了“未定义参考”。我用gcc -W -Wall -c util.c -o util.o \n cd.. gcc -W -Wall -c prova.c - prova.o \n gcc -o prova.exe prova.o Utils\util.o 肯定我仍然缺少添加opencl 库。但它们在标准位置(我将它们包含在 中,所以我应该添加什么?顺便说一句,谢谢你的帮助!
  • Ps:感谢您澄清 gcc 命令的使用!!
  • @Makers_F:我添加了一些使用其他路径库的示例。如果您使用-l 语法,则可以使用-L 指定其他库搜索路径。
  • 呜呜呜|你好酷!我设法编译它!在 AMD APP 文件夹中,我找到了一个 libOpenCl.a,包括这个,在你(伟大的)帮助下,我设法运行了该程序。我仍然不明白的是,当我已经在我的程序中包含了 openCL 头文件(并且预处理器应该添加它们)时,为什么还要链接一个外部库。他们(AMD)如何获得这个库?我无法编译头文件..顺便说一句,现在它可以工作了!!非常感谢你陪我度过的所有时间!!
  • @Makers_F:您应该考虑一下编译和链接过程。头文件只告诉编译器一个函数int foo();存在 某处,但它没有告诉它这个函数实际上是什么。编译器可以生成使用 foo 的代码,但该代码仍将具有未解析的foo 符号,而不是实际代码。获取未解析符号的所有代码并制作一个独立的可执行文件是链接器的工作。库函数的实现在库.a文件中。标题中没有实际代码!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多