包括 gsl_type.h。文件未找到

Rem*_*i.b 5 c compiler-errors makefile compilation

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

我有一些使用 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
Run Code Online (Sandbox Code Playgroud)

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

#include </opt/local/include/gsl/gsl_randist.h>
#include </opt/local/include/gsl/gsl_rng.h>
Run Code Online (Sandbox Code Playgroud)

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

编辑 1

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

编辑 2

gsl在我的电脑周围移动了我的文件夹,试图从不同的路径包含。并且发生了一些有趣的事情。例如,当我将gsl文件夹放入Users/remi/Documents/Biologie/programing/C/并写入 (in CFLAGS) 时

-I/Users/remi/Documents/Biologie/programing/C/ 
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

R_wrapper.c:43:10: fatal error: 'gsl_randist.h' file not found
#include <gsl_randist.h> // goal.
Run Code Online (Sandbox Code Playgroud)

当我写(在CFLAGS

Users/remi/Documents/Biologie/programing/C/gsl
Run Code Online (Sandbox Code Playgroud)

我收到此错误消息:

"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>" 
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 5

将评论转移到答案

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

#include <gsl/gsl_randist.h>
Run Code Online (Sandbox Code Playgroud)

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

-I/Users/remi/Documents/Biologie/programing/C/
Run Code Online (Sandbox Code Playgroud)

在您尝试的命令行上。

你应该阅读文档,如果它说写这些:

#include <gsl/gsl_randist.h>
#include "gsl/gsl_randist.h"
Run Code Online (Sandbox Code Playgroud)

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

Beta回答还指出

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

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

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

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

小心那些也很可爱的人../somedir/header.h- 请参阅相对路径的好处是什么,例如“../include/header.h”作为标题?.


我观察到GNU 科学图书馆手册有一个示例程序,它启动:

#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>
Run Code Online (Sandbox Code Playgroud)

并在部分编译和链接说:

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

#include <gsl/gsl_math.h>
Run Code Online (Sandbox Code Playgroud)

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