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 文件中,我试图重命名我的目录以便路径更传统,但操作系统没有给我重新命名权opt成usr(这可能使明显的感觉)。我还没有创建makefile,也没有完全理解它。我想我需要-I在CFLAGSOR 中某处的参数之后修改路径LFLAGS。
编辑 1
我R_wrapper.c在我的实验室计算机上进行了更改以摆脱#include <...>. 编译失败,正如@Beta 预测的那样。然后,我更改了我的 makefile 以添加-I/opt/local/include/gsl到CFLAGS. 我不知道你的意思是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/gsl是gsl文件夹在我电脑上的位置。所以我在你的程序中被困在这里。
编辑 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)
将评论转移到答案
从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)
那么这就是您应该在代码中编写的内容,因为(正如您发现的那样),如果不这样做,它将无法工作。
一般来说,
#include除非真的必须,否则将路径写入语句是个坏主意;它会导致这种问题。
我同意,但会更强烈地说明:
#include永远不要在语句中写入完整的路径。如果你真的编写它们,它会从根本上限制你的代码的可移植性。您不能依赖其他人的机器在安装在您系统上的同一位置安装软件。如果你在开源软件中尝试过,你会在法庭外被嘲笑。
小心那些也很可爱的人../somedir/header.h- 请参阅相对路径的好处是什么,例如“../include/header.h”作为标题?.
#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>
Run Code Online (Sandbox Code Playgroud)
并在部分编译和链接说:
库头文件安装在它们自己的
gsl目录中。您应该编写任何带有gsl/目录前缀的预处理器包含语句,因此,Run Code Online (Sandbox Code Playgroud)#include <gsl/gsl_math.h>如果该目录未安装在编译器的标准搜索路径上,您还需要将其位置作为命令行标志提供给预处理器。
gsl目录的默认位置是/usr/local/include/gsl.