Linux/Makefile: 创建一个像在特定目录中一样执行的二进制文件
Linux/Makefile: Creating a binary that executes as if it were in a specific directory
我有以下文件夹结构:
include/
src/
data/
binary-file
makefile
我会像这样执行二进制文件:./binary-file
但现在我希望我的二进制文件在它自己的文件夹中,如下所示:
bin/ <- binary-file is in here now
include/
src/
data/
makefile
当我像这样从主文件夹执行它时一切正常:bin/binary-file
但是如果我在主文件夹之外的另一个文件夹中,程序将无法正常运行并且无法找到#include 的路径。例如,如果我在 bin/ 文件夹中,如果我这样执行它,程序将表现不佳:./binary-file
我的问题是:如何让我的 makefile 或二进制文件像在主文件夹中一样从我系统的任何地方执行?
在我的 makefile 中,我所做的更改是:
$(CC) $(CFLAGS) -I$(IDIR) -I$(BDIR) -I$(DDIR) -o $(PROG) $^ $(LFLAGS)
至
$(CC) $(CFLAGS) -I$(IDIR) -I$(BDIR) -I$(DDIR) -o $(BDIR)/$(PROG) $^ $(LFLAGS)
您的数据文件名需要为"../data/xml/file.xml"
。
"../"
是相对路径,意思是"one folder back"。 "../../etc"
表示返回两个文件夹。
可能你问错了问题:构建系统与程序执行无关。
但是,如果您要寻找答案,如何使我的程序正确使用相对于程序安装定位的数据,那么这里就是答案。
当您的程序 main
被执行时,它会获取二进制路径作为第一个参数(索引 0
)。该路径可以是相对路径或绝对路径,但无论如何它都可以让您找到 base 目录。
这些也是有用的链接:
- How do I find the location of the executable in C?
- Finding current executable's path without /proc/self/exe
在这里你可以如何使用第一个参数:
#include <linux/limits.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
int main(int argc, char *argv[])
{
char datadir[PATH_MAX];
strncpy(datadir, argv[0], sizeof(datadir));
dirname(datadir);
strncat(datadir, "/../data", sizeof(datadir));
printf("Data dir: %s\n", datadir);
return 0;
}
该程序采用以下部署:
ROOT <- Can be anywhere on file system
+--bin
| +--- <- application is here...
+--data
+--- <- Data files are located here...
好的,基于您最近的通讯网络
@thurizas I have some data in my DDIR that my binary uses ("data/xml/file.xml"). When I execute the binary from the main folder: /bin/binary-file, everything works. But when I execute the binary file from the /bin/ folder: ./binary-file, it is unable to load "data/xml/file.xml"
硬编码数据文件的绝对路径(比如 /home/brandonto/projects/data/xml/file.xml ....假设是 *nix 类型的文件系统)。显然,无论您的可执行文件位于何处,它都可以找到数据文件。不利的一面是,如果您移动二进制文件,它将停止工作。
添加一个命令行选项来设置数据路径。例如,假设您选择应用程序数据文件的默认位置为 /usr/share/brandonto/myapp/data
,您可以将其硬编码到应用程序中。现在允许用户使用命令行参数来调整找到文件的位置。您的逻辑是,如果给出了命令行参数,则使用它,否则使用默认位置。有利的一面是您可以从任何地方执行,用户可以根据个人喜好移动内容,并且如果需要,您可以拥有两组数据文件(比如一组用于测试,一组用于生产)。不利的一面是,您的程序变得有点复杂,如果用户确实将数据文件移动到某个不寻常的地方,则每次他启动应用程序时都必须输入更多内容。例如;
./myapp -- would use the default location for the data files
./myapp -f <somepath> -- would use the files in <somepath> over ridding the default
还有一些其他选项,例如配置文件(这让我们回到与您最初的问题非常相似的问题:))
我有以下文件夹结构:
include/
src/
data/
binary-file
makefile
我会像这样执行二进制文件:./binary-file
但现在我希望我的二进制文件在它自己的文件夹中,如下所示:
bin/ <- binary-file is in here now
include/
src/
data/
makefile
当我像这样从主文件夹执行它时一切正常:bin/binary-file
但是如果我在主文件夹之外的另一个文件夹中,程序将无法正常运行并且无法找到#include 的路径。例如,如果我在 bin/ 文件夹中,如果我这样执行它,程序将表现不佳:./binary-file
我的问题是:如何让我的 makefile 或二进制文件像在主文件夹中一样从我系统的任何地方执行?
在我的 makefile 中,我所做的更改是:
$(CC) $(CFLAGS) -I$(IDIR) -I$(BDIR) -I$(DDIR) -o $(PROG) $^ $(LFLAGS)
至
$(CC) $(CFLAGS) -I$(IDIR) -I$(BDIR) -I$(DDIR) -o $(BDIR)/$(PROG) $^ $(LFLAGS)
您的数据文件名需要为"../data/xml/file.xml"
。
"../"
是相对路径,意思是"one folder back"。 "../../etc"
表示返回两个文件夹。
可能你问错了问题:构建系统与程序执行无关。
但是,如果您要寻找答案,如何使我的程序正确使用相对于程序安装定位的数据,那么这里就是答案。
当您的程序 main
被执行时,它会获取二进制路径作为第一个参数(索引 0
)。该路径可以是相对路径或绝对路径,但无论如何它都可以让您找到 base 目录。
这些也是有用的链接:
- How do I find the location of the executable in C?
- Finding current executable's path without /proc/self/exe
在这里你可以如何使用第一个参数:
#include <linux/limits.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
int main(int argc, char *argv[])
{
char datadir[PATH_MAX];
strncpy(datadir, argv[0], sizeof(datadir));
dirname(datadir);
strncat(datadir, "/../data", sizeof(datadir));
printf("Data dir: %s\n", datadir);
return 0;
}
该程序采用以下部署:
ROOT <- Can be anywhere on file system
+--bin
| +--- <- application is here...
+--data
+--- <- Data files are located here...
好的,基于您最近的通讯网络
@thurizas I have some data in my DDIR that my binary uses ("data/xml/file.xml"). When I execute the binary from the main folder: /bin/binary-file, everything works. But when I execute the binary file from the /bin/ folder: ./binary-file, it is unable to load "data/xml/file.xml"
硬编码数据文件的绝对路径(比如 /home/brandonto/projects/data/xml/file.xml ....假设是 *nix 类型的文件系统)。显然,无论您的可执行文件位于何处,它都可以找到数据文件。不利的一面是,如果您移动二进制文件,它将停止工作。
添加一个命令行选项来设置数据路径。例如,假设您选择应用程序数据文件的默认位置为
/usr/share/brandonto/myapp/data
,您可以将其硬编码到应用程序中。现在允许用户使用命令行参数来调整找到文件的位置。您的逻辑是,如果给出了命令行参数,则使用它,否则使用默认位置。有利的一面是您可以从任何地方执行,用户可以根据个人喜好移动内容,并且如果需要,您可以拥有两组数据文件(比如一组用于测试,一组用于生产)。不利的一面是,您的程序变得有点复杂,如果用户确实将数据文件移动到某个不寻常的地方,则每次他启动应用程序时都必须输入更多内容。例如;./myapp -- would use the default location for the data files ./myapp -f <somepath> -- would use the files in <somepath> over ridding the default
还有一些其他选项,例如配置文件(这让我们回到与您最初的问题非常相似的问题:))