【问题标题】:Do not manage linking library with clang不要使用 clang 管理链接库
【发布时间】:2013-03-19 23:46:50
【问题描述】:

我想用libuvhttp-parser 建立一个网络服务器。

目前的项目结构是

Makefile

/src
  /main.c

/deps
  /libuv (git clone of libuv)
  /http-parser (git clone of http-parser)

在 main.c 中我定义了以下包括:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "uv.h"
#include "http_parser.h"

Makefile 看起来像:

LDFLAGS = -L deps/libuv

main: libuv http-parser
    $(CC) src/main.c -o main.out deps/libuv/libuv.a deps/http-parser/http_parser.o $(LDFLAGS)

libuv:
    $(MAKE) -C deps/libuv libuv.a

http-parser:
    $(MAKE) -C deps/http-parser http_parser.o

clean:
    rm deps/libuv/libuv.a
    rm deps/http-parser/http_parser.o

当编译器尝试链接 http_parser 时会发生这种情况。

make -C deps/libuv libuv.a
make[1]: `libuv.a' is up to date.
make -C deps/http-parser http_parser.o
make[1]: `http_parser.o' is up to date.
cc src/main.c -o main.out deps/libuv/libuv.a deps/http-parser/http_parser.o
src/main.c:5:10: fatal error: 'http_parser.h' file not found
#include "http_parser.h"
         ^
1 error generated.
make: *** [main] Error 1

当我从包含和 Makefile 中删除 http_parser 时,我得到一个奇怪的 libuv 构建错误:

Undefined symbols for architecture x86_64:
  "_CFArrayCreate", referenced from:
      _uv__fsevents_init in libuv.a(fsevents.o)
  "_CFRunLoopAddSource", referenced from:
      _uv__cf_loop_runner in libuv.a(darwin.o)
  "_CFRunLoopGetCurrent", referenced from:
      _uv__cf_loop_runner in libuv.a(darwin.o)
  "_CFRunLoopRemoveSource", referenced from:
      _uv__cf_loop_runner in libuv.a(darwin.o)
  "_CFRunLoopRun", referenced from:
      _uv__cf_loop_runner in libuv.a(darwin.o)
  "_CFRunLoopSourceCreate", referenced from:
      _uv__platform_loop_init in libuv.a(darwin.o)
  "_CFRunLoopSourceSignal", referenced from:
      _uv__cf_loop_signal in libuv.a(darwin.o)
  "_CFRunLoopStop", referenced from:
      _uv__platform_loop_delete in libuv.a(darwin.o)
  "_CFRunLoopWakeUp", referenced from:
      _uv__cf_loop_signal in libuv.a(darwin.o)
  "_CFStringCreateWithCString", referenced from:
      _uv__fsevents_init in libuv.a(fsevents.o)
  "_CFStringGetSystemEncoding", referenced from:
      _uv__fsevents_init in libuv.a(fsevents.o)
  "_FSEventStreamCreate", referenced from:
      _uv__fsevents_init in libuv.a(fsevents.o)
  "_FSEventStreamInvalidate", referenced from:
      _uv__fsevents_close in libuv.a(fsevents.o)
  "_FSEventStreamRelease", referenced from:
      _uv__fsevents_close in libuv.a(fsevents.o)
  "_FSEventStreamScheduleWithRunLoop", referenced from:
      _uv__fsevents_schedule in libuv.a(fsevents.o)
  "_FSEventStreamStart", referenced from:
      _uv__fsevents_schedule in libuv.a(fsevents.o)
  "_FSEventStreamStop", referenced from:
      _uv__fsevents_close in libuv.a(fsevents.o)
  "_kCFRunLoopDefaultMode", referenced from:
      _uv__cf_loop_runner in libuv.a(darwin.o)
      _uv__fsevents_schedule in libuv.a(fsevents.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1

从昨天开始我就被这个问题困住了,完全失去了希望..

Makefile 的当前状态:

LDFLAGS = -Ldeps/libuv
INCLFLAGS = -Ideps/http-parser

main.o: libuv.a http-parser.o
    $(CC) src/main.c $(INCLFLAGS) -o main.o deps/libuv/libuv.a deps/http-parser/http_parser.o $(LDFLAGS)

libuv.a:
    $(MAKE) -C deps/libuv libuv.a

http-parser.o:
    $(MAKE) -C deps/http-parser http_parser.o

clean:
    rm deps/libuv/libuv.a
    rm deps/http-parser/http_parser.o

详细输出:

#include "..." search starts here:
#include <...> search starts here:
 deps/libuv
 deps/http-parser
 /usr/local/include
 /usr/bin/../lib/clang/4.2/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.
 "/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.8.0 -o main.o -Ldeps/libuv /var/folders/4l/zj55m1gn289f6v04zfbl59bm0000gn/T/main-sRhCLM.o deps/libuv/libuv.a deps/http-parser/http_parser.o -lSystem /usr/bin/../lib/clang/4.2/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
  "_CFArrayCreate", referenced from:
      _uv__fsevents_init in libuv.a(fsevents.o)
  "_CFRunLoopAddSource", referenced from:
      _uv__cf_loop_runner in libuv.a(darwin.o)

【问题讨论】:

    标签: c compiler-construction linker makefile clang


    【解决方案1】:

    我怀疑 http_parser.h 与 main.c 不在同一目录中。要么将该文件复制到那里,要么最好更新您的 INCLUDE 路径。

    HTTP_PARSER_INCLUDE= -I/home/wherever/http_parser
    
    main: libuv http-parser
        $(CC) src/main.c -o main.out $(HTTP_PARSER_INCLUDE) deps/libuv/libuv.a deps/http-parser/http_parser.o $(LDFLAGS)
    

    由于删除 http_parser.h 而导致的另一个错误可能只是由于一开始就没有构建干净而导致的噪音。您在上面声明的“main”规则构建“main.out”而不是“main”。这也可能与 Make 试图无中生有有关。

    更新 - 您需要在命令行中添加 -framework CoreFoundation 以消除链接器错误。

    【讨论】:

    • 您对包含标志的看法似乎是正确的。 http_parser 不再有错误,但链接 libuv 的错误仍然存​​在。我添加了更新后的 Makefile,它现在使用与输出文件相同的规则名称
    • 您使用的是 Mac,对吗?您需要在命令行中添加“-framework CoreFoundation”。
    • 感谢这几乎是它。我添加了你的标志,但那里还有一些未定义的符号。所以我检查了 libuv makefile 以获得更多框架并在这里找到它们:github.com/joyent/libuv/blob/master/config-unix.mk#L76-L78 现在它可以工作了。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多