创建共享库时出现Clang错误

时间:2013-04-21 02:22:11

标签: gcc llvm clang llvm-clang

我想在MBP上编译共享库,并根据给定here的建议,我已切换到clang(来自gcc)以创建共享库。我的makefile是:

CC = clang
CFLAGS = -c -fPIC -Wall -O3 -lpthread -g
BaseDir = /Users/admin/Prog/
Include = -I$(BaseDir)UMFPACK/Include -I$(BaseDir)AMD/Include -I$(BaseDir)SuiteSparse_config
Lib = -L$(BaseDir)UMFPACK/Lib -L$(BaseDir)AMD/Lib -L$(BaseDir)GotoBLAS2 -L$(BaseDir)SuiteSparse_config
AddFiles = -lumfpack -lamd -lgoto2 -lsuitesparseconfig
StaticLibs = $(BaseDir)GotoBLAS2/libgoto2.a $(BaseDir)UMFPACK/Lib/libumfpack.a $(BaseDir)AMD/Lib/libamd.a $(BaseDir)SuiteSparse_config/libsuitesparseconfig.a

all: TDS.o TDSJac.o ExtraRoutines.o CalcVFC.o TDS.h
        $(CC) $(Include) $(Lib) $(AddFiles) -dynamiclib -lpthread -o libTDS.so $^ -lm -g $(StaticLibs)

TDS.o: TDS.c TDS.h
        $(CC) $(Include) $(CFLAGS) $^

TDSJac.o: TDSJac.c TDS.h
        $(CC) $(CFLAGS) $^

ExtraRoutines.o: ExtraRoutines.c TDS.h
        $(CC) $(CFLAGS) $^

CalcVFC.o: CalcVFC.c TDS.h
        $(CC) $(CFLAGS) $^

MexFile: TDSGateway.c
        mex -g -largeArrayDims -ldl TDSGateway.c

Move:
        mv libTDS.so ../../
        mv TDSGateway.mexmaci64 ../../

我在这里做的是: 1)仅编译TDS.cTDSJac.cExtraRoutines.cCalcVFC.c以创建四个相应的目标文件。 2)使用以下命令合并目标文件并创建共享库:

clang -I(Some folders) -L(Some folders) -l(Some libraries) -shared -lpthread -o libTDS.so TDS.o TDSJac.o ExtraRoutines.o CalcVFC.o TDS.h -lm -g
clang: error: cannot specify -o when generating multiple output files

由于我对clang绝对不熟悉,我不知道Makefile有什么问题。 (如果我将CC=clang替换为CC=gcc,一切正常。) 我在互联网上搜索没有成功。 clang的手册页对共享库一无所知。我甚至无法从clang homepage中得到任何东西。如果能帮助我解决这个问题,我们将不胜感激。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我昨天遇到了几乎同样的问题。 但我从未使用过cmake。我正在使用我公司自己的makefile系统,所以我可以告诉你,到目前为止我解决了什么问题。

Clang在给出错误提示的正确提示方面仍有些麻烦。 链接错误是:

/usr/bin/ld: /usr/lib/crt1.o: relocation R_X86_64_32 against `_DYNAMIC' can not be used when making a shared object; recompile with -fPIC

我解决了问题,因为我知道-shared参数必须在-o X.o参数后面。我认为这也不是你的情况。你应该先尝试一下。

在我们的例子中,我还必须使用-WL或-L来解析LFlags(afaik,无论你选择哪一个,但我读到了与-Wl有关的clang bug)。 但是,当你使用cmake时,你需要在多大程度上解析LFlags。

答案 1 :(得分:1)

您已将标题(TDS.h)列为依赖项,这很好,但您已使用$^作为输入,其中包括所有依赖项。您不应该将标题列为输入。它根本不应该在命令行上,而在clang这实际上是一个错误。

错误消息不明确但易于解决。你有两个选择:

  1. 明确而不是使用$^。您可以使用变量作为输入,将另一个变量用于依赖项,例如;或
  2. 使用中间.o个文件而不是.c个文件作为.so的输入。 *.o文件可以依赖于它们包含的任何.h