【问题标题】:Include gsl_type.h. File not found包括 gsl_type.h。文件未找到
【发布时间】:2015-02-01 21:16:50
【问题描述】:

这似乎是一个常见问题,但我无法解决这个问题。

我有一些使用 makefile 编译的 .c 代码。目标是创建一个共享对象 (.so),以便我可以从 R 运行 C 代码。

这是我的生成文件:

obs = R_wrapper.o G.o develop.o utilities.o
CFLAGS = -arch x86_64 -std=gnu99 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/x86_64 -DNDEBUG  -I/usr/local/include    -fPIC  -g -O3  -c
LFLAGS = -arch x86_64 -std=gnu99 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/lib -O3 -lgsl -lm -lgslcblas

R_wrapper : $(obs)
    $gcc $(LFLAGS) $(obs) -o R_wrapper.so

R_wrapper.o : R_wrapper.c constants.h develop.h G.h
    $gcc $(CFLAGS) R_wrapper.c

G.o : G.c G.h constants.h utilities.h develop.h 
    $gcc $(CFLAGS) G.c develop.c

develop.o : develop.c develop.h G.h constants.h
    $gcc $(CFLAGS) develop.c

utilities.o : utilities.c develop.h
    $gcc $(CFLAGS) utilities.c

它在我实验室的计算机上运行良好,但在我的个人计算机上却无法运行。导致此问题的原因是我的 R_wrapper.c 开头的这两行。

#include </opt/local/include/gsl/gsl_randist.h>
#include </opt/local/include/gsl/gsl_rng.h>

我试图移动这些文件并给出不同的路径,将文件放在与我的 R_wrapper 文件相同的目录中的 gal_type.h 文件中,我试图重命名我的目录,以便路径更传统,但操作系统没有给我将opt 重命名为usr 的权利(这可能很明显)。我还没有创建makefile,也没有完全得到它。我想我需要在CFLAGSLFLAGS 中某处的-I 参数之后修改路径。

编辑 1

我在我的实验室计算机上更改了R_wrapper.c,以摆脱#include &lt;...&gt; 中的整个路径。正如@Beta 预测的那样编译失败。然后,我更改了我的makefile,将-I/opt/local/include/gsl 添加到CFLAGS。我不知道您所说的Verify that the makefile still works. 是什么意思我试图在我的实验室计算机上使用我编辑的makefile 进行编译,但它失败了。然后我重新编辑了我的生成文件,将-I/opt/local/include/gsl 更改为-I/usr/local/include/gsl,因为在我的实验室计算机上,gsl 文件夹位于/usr/local/include/gsl-I/opt/local/include/gsl 是我电脑上gsl 文件夹的位置。所以我在你的程序中被困在这里。

编辑 2

我在我的计算机上移动了我的gsl 文件夹,试图从不同的路径中包含。并且发生了一些有趣的事情。例如,当我将gsl 文件夹放入Users/remi/Documents/Biologie/programing/C/ 并写入(CFLAGS

-I/Users/remi/Documents/Biologie/programing/C/ 

我收到此错误:

R_wrapper.c:43:10: fatal error: 'gsl_randist.h' file not found
#include <gsl_randist.h> // goal.

当我写信时(CFLAGS

Users/remi/Documents/Biologie/programing/C/gsl

我收到此错误消息:

"In file included from R_wrapper.c:43: /Users/remi/Documents/Biologie/programing/C/gsl/gsl_randist.h:22:10: fatal error: 
      'gsl/gsl_rng.h' file not found
#include <gsl/gsl_rng.h>" 

【问题讨论】:

  • 从编辑 2 中未找到 gsl/gsl_rng.h 的消息来看,您应该在源代码中编写 #include &lt;gsl/gsl_randist.h&gt;(在标头名称前加上 gsl/ 的路径前缀)。这是一个常见的约定。然后在-I 选项中指定包含gsl 子目录的目录名称,该子目录包含gsl_*.h 标头。你应该阅读文档,如果上面写着#include &lt;gsl/gsl_randist.h&gt;#include "gsl/gsl_randist.h",那你应该在你的代码中写,因为(因为你已经发现了艰难的方式)如果你不这样做,它就行不通.
  • @JonathanLeffler 哦!这解决了我的问题!唷。我在这个问题上挣扎了很多……这实际上很简单(像往常一样)。非常感谢!您能根据您的评论做出回答,以便我检查吗?
  • 包含库使用:#include

标签: c compilation compiler-errors makefile


【解决方案1】:

转评论回答

从编辑 2 中提到的关于 gsl/gsl_rng.h 未找到的消息来看,你应该写

#include <gsl/gsl_randist.h>

(在标头名称前带有gsl/ 的路径前缀)在您的源代码中。这是一个常见的约定。然后在-I 选项中指定包含gsl 子目录的目录名称,该子目录包含gsl_*.h 标头。在您的编辑 2 中,您说您将 gsl 目录放入 /Users/remi/Documents/Biologie/programing/C/,因此您可以正确使用:

-I/Users/remi/Documents/Biologie/programing/C/

在你尝试的命令行上。

你应该阅读文档,如果它说写以下任何一个:

#include <gsl/gsl_randist.h>
#include "gsl/gsl_randist.h"

那么这就是您应该在代码中编写的内容,因为(正如您已经发现的艰难方式)如果您不这样做,它将无法工作。

Betaanswer 也声明

一般来说,将路径写入#include 语句是一个坏主意,除非你真的必须这样做;它会导致这种问题。

我同意,但会更强烈地声明:

  • 永远不要将完整路径写入#include 语句。

如果您确实编写它们,则会从根本上限制代码的可移植性。您不能依赖其他人的机器将软件安装在与您的系统相同的位置。如果你在开源软件中尝试过,你会被嘲笑。

提防那些用../somedir/header.h 变得可爱的人——见What are the benefits of a relative path such as "../include/header.h" for a header?


我观察到GNU Scientific Library 手册有一个example program 开头:

#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>

Compiling and Linking 上的部分说:

库头文件安装在它们自己的gsl 目录中。因此,您应该编写任何带有 gsl/ 目录前缀的预处理器包含语句,

#include <gsl/gsl_math.h>

如果该目录未安装在编译器的标准搜索路径上,您还需要将其位置作为命令行标志提供给预处理器。 gsl 目录的默认位置是/usr/local/include/gsl

【讨论】:

    【解决方案2】:

    一般来说,将路径写入#include 语句是一个坏主意,除非你真的必须这样做;它会导致这种问题。

    在您的实验室计算机上,编辑R_wrapper.c

    #include <gsl_randist.h>
    #include <gsl_rng.h>
    

    现在构建应该失败了。如果是这样,那么这将验证您没有其他版本的这些标题浮动,或链接到它们,或其他任何东西。确认它失败,然后撤销更改,并确认它再次工作。

    然后将-I/opt/local/include/gsl 添加到CFLAGS验证 makefile 是否仍然有效。

    然后再次编辑R_wrapper.c;现在构建应该成功了。

    决定您希望将这些文件(gsl_randist.hgsl_rnd.h)保存在个人计算机上的哪个位置,并在您的家庭版 makefile 上相应地修改 CFLAGS

    一旦所有这些都完美运行,我们可以向您展示如何编写一个可以在两台机器上运行的 makefile。

    另外,您可以通过其他方式改进您的 makefile 规则,但我必须先问一个问题:

    G.o : G.c G.h constants.h utilities.h develop.h 
        $gcc $(CFLAGS) G.c develop.c
    

    G.o 真的需要develop.c 吗?如果是这样,那么您可能应该重新检查您的源文件,因为这真的很不卫生。

    【讨论】:

    • 非常感谢@Beta 的帮助。所以我在我的实验室计算机上更改了R_wrapper.c。摆脱#include &lt;...&gt; 中的整个路径。编译失败,确实。然后我更改了我的make文件以将-I/opt/local/include/gsl添加到CFLAGS。我不知道Verify that the makefile still works. 是什么意思我试图在我的实验室计算机上使用我编辑的makefile 进行编译,但它失败了。然后我编辑了我的makefile,将-I/opt/local/include/gsl更改为-I/usr/local/include/gsl,因为在我的实验室计算机上,gal文件夹位于/usr/local/include/gsl
    • -I/opt/local/include/gsl 是我电脑上gsl 文件夹的位置。所以我在你的程序中被困在这里。
    • @Remi.b:我认为你错过了一步。 “撤消更改并确认它再次起作用。” 也就是说,恢复到 R_wrapper.c 的原始版本(包含路径)并验证构建系统是否再次起作用。 然后尝试将-I/opt/local/include/gsl 添加到CFLAGS。小步骤。
    • 好的,我有一段时间无法处理这个问题。我现在回来了。按步骤: 1) 在ComputerLabR_wrapper 上,再次清除路径。它无法编译。 2) 在ComputerLabR_wrapper 上,将路径放回原处。它编译。 3) 在ComputerLab 上添加-I/opt/local/include/gslCFLAGS。它编译 4) 在ComputerLab 上,在R_wrapper 上,去掉路径。它编译。5) 确定gsl 文件夹在我的计算机上的位置。决定了! 6)相应地更改CFLAGS(在我的电脑上的Makefile上)。完毕! 7)它不编译!我错过了什么?谢谢
    • 请查看我的问题中的更新。这可能有助于解决问题或可能有助于理解我不理解的内容!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 2018-12-16
    • 2017-06-02
    相关资源
    最近更新 更多