使用clang ++在Mac OSX上创建动态库

问题描述 投票:0回答:2

我想学习如何用C ++制作共享库。因此,我找到了一些生成Mandelbrot PPM图像的逻辑,并将其封装在src/mandelbrot.cpp中(并附带了头文件include/mandelbrot.cpp)。目录树如下所示:

$ tree
.
├── Makefile
├── include
│   └── mandelbrot.h
├── lib
│   └── mandelbrot.dylib
└── src
    ├── client.cpp
    ├── main
    ├── main.cpp
    ├── mandelbrot.cpp
    └── mandelbrot.o

[目标是src/client.cpp使用lib/mandelbrot.dylib绘制分形而无需访问src/mandelbrot.cppsrc/mandelbrot.o

Makefile:

.PHONY=clean

main: src/mandelbrot.o
    clang++ src/main.cpp -o src/main src/mandelbrot.o -I ./include

src/mandelbrot.o:
    clang++ -c src/mandelbrot.cpp -o src/mandelbrot.o -I ./include

clean:
    rm src/*.o
    rm lib/*.dylib

lib/mandelbrot.dylib:
    clang++ -dynamiclib -o lib/mandelbrot.dylib src/mandelbrot.cpp -I ./include

src/client: lib/mandelbrot.dylib
    clang++ src/client.cpp -o src/client -L ./lib -I ./include

在没有dylib的情况下运行可执行文件:

$ make main
clang++ src/main.cpp -o src/main src/mandelbrot.o -I ./include
$ ./src/main  # runs fine!

但是编译src/client.cpp时无法链接共享库:

$ make src/client
clang++ src/client.cpp -o src/client -L ./lib -I ./include
Undefined symbols for architecture x86_64:
  "fractal::Mandelbrot::writeToFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
      _main in client-e344c7.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: *** [src/client] Error 1

即使该符号似乎在dylib中:

$ file lib/mandelbrot.dylib 
lib/mandelbrot.dylib: Mach-O 64-bit dynamically linked shared library x86_64

$ nm -C lib/mandelbrot.dylib | grep writeToFile
0000000000001460 T fractal::Mandelbrot::writeToFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)

我正在尝试更深入地了解链接/编译过程。如何进行我要进行的设置以演示我想做什么?

c++ makefile clang++ dylib
2个回答
1
投票

尝试像libmandelbrot.dylib这样命名您的库以匹配-lmandelbrot标志


0
投票

贷方@Daniel寻求答案,但略述原因。

我可以通过重命名mandelbrot.dylib-> libmandelbrot.dylib使编译工作,如@daniel的答案所建议。

我研究了man ld(链接器),发现以下定义:

-lx    This option tells the linker to search for libx.dylib or libx.a in the library search path.  If string x is of the form y.o, then that file is searched for in the same places, but without prepending
       `lib' or appending `.a' or `.dylib' to the filename.

因此,如果要随意命名动态加载的库(由于某种原因,不喜欢在名称前加上libxxxx的魔力,那么您就必须这样做(我已经证实了这是可行的:]

lib/whatever.o:
    clang++ -dynamiclib -o lib/whatever.o src/mandelbrot.cpp -I ./include

src/client: lib/whatever.o
    clang++ src/client.cpp -o src/client -L ./lib -I ./include -l whatever.o

TL; DR =通过将-l选项作为以.o结尾的文件名,链接器直接在-L指定的目录中查找-l中指定的确切文件名。否则-l foo -L /path/搜索/path/libfoo.[dylib|a]

© www.soinside.com 2019 - 2024. All rights reserved.