相关疑难解决方法(0)

为什么我必须为 LLVM 链接这些库两次?

我正在尝试编译一个示例 LLVM 程序。链接器步骤使用此命令。

llvm-config-3.2 --ldflags --libs
Run Code Online (Sandbox Code Playgroud)

这会产生以下命令。

g++  -o bin/Debug/test-llvm obj/Debug/main.o   -L/usr/lib/llvm-3.2/lib  -lpthread -lffi -ldl -lm  (a boat load of LLVM libraries here)
Run Code Online (Sandbox Code Playgroud)

但是,它无法链接。我收到这样的错误。

undefined reference to ffi_type_float
Run Code Online (Sandbox Code Playgroud)

所以,我在最后添加了-lffi和。-ldl

g++  -o bin/Debug/test-llvm obj/Debug/main.o   -L/usr/lib/llvm-3.2/lib  -lpthread -lffi -ldl -lm  (a boat load of LLVM libraries here) -lffi -ldl
Run Code Online (Sandbox Code Playgroud)

所以,是的,它们在命令中出现两次......但它是这样工作的。为什么?它们在前面的论点中被明确引用。

c++ linker llvm

4
推荐指数
1
解决办法
867
查看次数

混合C和C++库

我在构建用C++编码的可执行文件时遇到了一个奇怪的问题,它使用的C++库本身依赖于C库.我使用gcc和使用g ++的所有其他源模块编译了构成C库的C模块.C和C++库都是静态库.

当我在C++源代码中包含来自C库的头文件时,我将其包装在extern"C"中:

extern "C"
{
  #include <c-library-header.h> 
}
Run Code Online (Sandbox Code Playgroud)

现在奇怪的是链接时得到"未定义的引用"错误,但这些错误取决于我列出库的顺序:

  • 如果我首先列出C库,则C++模块引用的该库中的所有符号都显示为"undefined".
  • 如果我首先列出C++库,那么C++模块引用的该库中的所有符号都显示为"undefined".

我本以为在g ++命令行中出现静态库的顺序是完全无关紧要的.有人有任何线索吗?

c c++ gnu

4
推荐指数
1
解决办法
483
查看次数

无法链接到libgfortran.a

我在我的系统上安装了gfortran,libgfortran.a可以找到该文件/usr/lib/gcc/x86_64-linux-gnu/4.6/.使用nm我确保函数_gfortran_compare_string在那里定义:

$ nm /usr/lib/gcc/x86_64-linux-gnu/4.6/libgfortran.a | grep _gfortran_compare_string
Run Code Online (Sandbox Code Playgroud)

返回

0000000000000000 T _gfortran_compare_string
0000000000000000 T _gfortran_compare_string_char4
Run Code Online (Sandbox Code Playgroud)

但是,我的CUDA-C程序的链接器会抛出错误:

/usr/local/cuda-6.0/bin/nvcc --cudart static -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/home/chung/lapack-3.5.0 -link -o  "pQP"  ./src/pQP.o   -lgfortran -llapacke -llapack -lcublas -lblas -lcurand
nvcc warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
/home/chung/lapack-3.5.0/liblapack.a(ilaenv.o): In function `ilaenv_':
ilaenv.f:(.text+0x81): undefined reference to `_gfortran_compare_string'
Run Code Online (Sandbox Code Playgroud)

以及另一个错误,再次与libgfortran有关:

/home/chung/lapack-3.5.0/liblapack.a(xerbla.o): In function `xerbla_':
xerbla.f:(.text+0x49): undefined reference to `_gfortran_st_write'
xerbla.f:(.text+0x54): undefined reference to `_gfortran_string_len_trim' …
Run Code Online (Sandbox Code Playgroud)

c linker cuda gfortran

4
推荐指数
1
解决办法
9009
查看次数

与静态库链接时未定义的引用,但与 src 编译时链接成功

我正在尝试使用 Boost::Test 为该库创建一个 C 库和一个 C++ 测试程序。我在这个问题中发布的代码是我的代码的简化,它显示了完全相同的问题。请帮忙!

这是目录结构。 childlib是我正在尝试创建的库,并且test是测试程序。

> tree
.
`-- src
    |-- main
    |   |-- c
    |   |   `-- childlib.c
    |   |-- childlib.h
    |   `-- makefile
    `-- test
        |-- cpp
        |   `-- test.cpp
        `-- makefile

5 directories, 5 files
Run Code Online (Sandbox Code Playgroud)

我可以childlib成功地制作成一个静态库:

> cd src/main    
> make
gcc -c -fPIC -o c/childlib.o c/childlib.c
ar rcs libchildlib.a c/childlib.o
ranlib libchildlib.a
Run Code Online (Sandbox Code Playgroud)

但是我无法通过链接来制作我的测试程序:

> cd ../test/
> make
g++ -I. -I../main -Imy_boost_install_dir/include -c -std=c++11 -o cpp/test.o cpp/test.cpp …
Run Code Online (Sandbox Code Playgroud)

c++ makefile linker-errors

4
推荐指数
1
解决办法
8659
查看次数

C编译错误 - 艰难地学习C(Ex 32)

我在练习32的学习C艰难的方法编译时遇到了很糟糕的时间.

我已经从创建者的GitHub仓库中逐字复制了代码,甚至克隆在一个新的存储库中.我已经浏览过其他存储库,除了Ubuntu之外还尝试了我的MacOSX等等.我似乎没有做任何事情就可以编译.

我使用的是Ubuntu 12.04(见下文).

这是我的文件结构(注意 - 这是我直接从练习32中包含文件时的文件结构.显然,当我克隆git存储库时,我得到更多文件.我使用diff来确保我的所有文件,包括我的make文件,在我的削减版本中完全类似于git存储库):

$ pwd
/usr/local/me/code/C/liblcthw


$ ls
bin  LICENSE  Makefile  README.md  src  tests

$ ls tests/
list_tests.c  minunit.h  runtests.sh

$ ls src/lcthw/
dbg.h  list.c  list.h
Run Code Online (Sandbox Code Playgroud)

这是我的make命令.

$ make
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  -fPIC   -c -o src/lcthw/list.o src/lcthw/list.c
ar rcs build/liblcthw.a src/lcthw/list.o
ranlib build/liblcthw.a
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG  build/liblcthw.a    tests/list_tests.c   -o tests/list_tests
tests/list_tests.c: In function ‘main’:
tests/list_tests.c:111:1: warning: parameter ‘argc’ set but not used …
Run Code Online (Sandbox Code Playgroud)

c

4
推荐指数
1
解决办法
1150
查看次数

不同库和链接顺序中的相同符号

我有2个库:test.1test.2.两个库都包含单个全局extern"C" void f();函数,具有不同的实现(仅cout用于测试).

我做了以下测试:

测试1动态链接:
如果我添加libtest.1.so,然后libtest.2.so在可执行文件的生成文件,然后调用f();main,libtest.1.so->f()被调用.
如果我更改makefile中的顺序,libtest.2.so->f()则调用

测试2静态链接:
静态库完全相同

测试3动态加载
手动加载库时,一切都按预期工作.


我预计多个定义会出错,这显然不会发生.

此外,这不会打破单一定义规则,因为情况不同.

它也不是一个依赖地狱(不是它与此有关),也不是任何链接惨败..

那么,这是什么呢?未定义的行为?未指明的行为?或者它确实取决于链接顺序?

有没有办法轻松检测到这种情况?


相关问题:
dlopen与链接开销
动态链接和动态加载之间的区别
使用-Bsymbolic函数是否存在缺点?
为什么库链接的顺序有时会导致GCC错误?
将两个共享库与一些相同的符号链接起来


编辑我做了两个测试,证实了这个UB:

我添加了第二个函数void g()test.1,而不是在test.2.

使用动态链接和.so库,同样的事情 - f以相同的方式调用,g也是可执行的(如预期的那样).

但是使用静态链接现在改变了一些事情:如果test.1之前 test.2,没有错误,test.1则会调用两个函数.
但是当订单更改时,会出现"多个定义"错误.

很明显,"不需要诊断"(参见@MarkB的答案),但有时候发生错误是"奇怪的",有时候 - 它没有.

无论如何,答案很清楚,并解释了上面的一切 - UB.

c c++ dynamic-linking multiple-definition-error static-linking

4
推荐指数
2
解决办法
3421
查看次数

Fortran和C++的混合编程:Fortran不能调用C++子程序

最近,我正在做一个项目,其中一些 C++ 子例程被 Fortran 脚本调用(Fortran 求解器打算具有一些数据后处理功能,该功能来自用 C++ 开发的库)。以下过程重播错误产生过程。在这里,我使用非常简单的 Fortran 和 C++ 脚本进行简单明了的演示。

一个简单的 Fortran 主程序调用 CXX 子程序: CXX 子程序 - sub1.cxx:

    #include <stdio.h>
    using namespace :: std;
    extern "C" void func_c_();
    void func_c_()
    {
         printf("%d\n", 100);
    }
Run Code Online (Sandbox Code Playgroud)

Fortran 主程序 - sub2.f90:

    program func_fortran
          implicit none
          call func_c()
    end program func_fortran
Run Code Online (Sandbox Code Playgroud)

编译它们:

    g++ -c sub1.cxx
    gfortran -o test sub2.f90 sub1.o
Run Code Online (Sandbox Code Playgroud)

我们得到可执行文件 - 测试。到目前为止,没有问题。

然后我们将 sub1.cxx 替换为 sub1.1.cxx。看起来像:

    #include <iostream>
    using namespace :: std; 
    extern "C" void func_c_();
    void func_c_()
    {
         cout …
Run Code Online (Sandbox Code Playgroud)

c++ fortran

4
推荐指数
1
解决办法
148
查看次数

与 fmt 链接错误:对 `std::string fmt::v6::internal::grouping_impl&lt;char&gt;(fmt::v6::internal::locale_ref)' 的未定义引用

在我们的项目中,我们决定在项目中使用最新的 fmt 版本(6.2.0),并主要使用 printf 功能,因为我们广泛使用 printf 进行日志记录。

我使用 fmt 包中包含的 CMakeLists.txt 在 Linux 机器上构建了 libfmt.a。在我的过程中,我将 libfmt include 目录包含在 target_link_libraries 中。在代码中我只使用了#include<fmt/printf.h>. 现在,当我编译代码时,代码被编译,但在链接时,我收到错误:还有更多错误,但以下是第一个,我相信如果这个问题得到解决,其余的将自动解决

abc.cpp:(.text._ZN3fmt2V68internal8groupingIcEESsNS1_10locale_refE[_ZN3fmt2v68internal8groupingIcEESsNS1_10locale_refE]+0X20): 未定义引用 `std::string fmt::v6::internal::grouping_impl(fmt::v6::internal:: locale_ref)'

我做了一些分析,发现这个函数的定义存在于format-inl.h中。我尝试将其包含在我的代码中,但仍然存在相同的链接问题。

现在,当我在代码中定义宏FMT_HEADER_ONLY时,链接起作用了。

我的问题是:当我链接库 libfmt.a 时,它无法找到该函数。为什么?我不想使用仅标题版本。

请让我知道如何解决这个问题。

c++ fmt

4
推荐指数
1
解决办法
4612
查看次数

Linux上C代码的编译错误(OSX上的相同代码编译)

我想在linux上编译一些我知道在OSX上编译的代码,但是我遇到了一些问题.

所有文件都有名为.h的头文件,所有文件都在同一目录下.我这样编译:

gcc *.c -std=c99 -lpthread
Run Code Online (Sandbox Code Playgroud)

虽然这段代码在OSX上编译,但我在Ubuntu安装上遇到了一堆奇怪的链接器错误.我错过了一些编译器选项吗?它是一个默认的Ubuntu服务器安装,带有附加软件包gccbuild-essential已安装.

In file included from errorLogger.h:24:0,
                 from configParser.h:17,
                 from configParser.c:9:
signalHandling.h:24:18: error: unknown type name ‘sigset_t’
configParser.c: In function ‘parseConfigFile’:
configParser.c:114:5: warning: implicit declaration of function ‘getline’ [-Wimplicit-function-declaration]
In file included from errorLogger.h:24:0,
                 from global.h:18,
                 from connection.h:19,
                 from connection.c:10:
signalHandling.h:24:18: error: unknown type name ‘sigset_t’
connection.c: In function ‘createConnectionQueue’:
connection.c:189:28: warning: assignment makes integer from pointer without a cast [enabled by default]
In file included from errorLogger.h:24:0,
                 from database.h:16,
                 from …
Run Code Online (Sandbox Code Playgroud)

c linux ubuntu linker gcc

3
推荐指数
2
解决办法
2万
查看次数

链接到 clang 时出错

我觉得我在这里错过了一些非常简单的东西。我想玩一下 clang,所以作为一个起点,我遵循了这个视频中的代码示例,大约 3:40。代码如下:

#include "clang-c/Index.h" // Note: These two lines were 
#include <stdio.h>         // omitted from the video slides
int main(int argc, char *argv[])
{
    CXIndex Index = clang_createIndex(0, 0);
    CXTranslationUnit TU = clang_parseTranslationUnit(Index, 0, argv, argc, 0, 0, CXTranslationUnit_None);
    for (unsigned I = 0, N = clang_getNumDiagnostics(TU); I != N; ++I)
    {
        CXDiagnostic Diag = clang_getDiagnostic(TU, I);
        CXString String = clang_formatDiagnostic(Diag, clang_defaultDiagnosticDisplayOptions());
        fprintf(stderr, "%s\n", clang_getCString(String));
        clang_disposeString(String);
    }
    clang_disposeTranslationUnit(TU);
    clang_disposeIndex(Index);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在视频中,他没有声明他省略了这两个#include指令。我想我在上面的例子中正确填写了这些。他还省略了文件的编译和链接方式,这是我遇到问题的部分。按照 …

c linker clang linker-errors

3
推荐指数
1
解决办法
2706
查看次数