2015-02-16 2 views
1

I имеет следующую структуру папок:Относительные пути из двоичного файла

bin/ <-binary-file is in here 
include/ 
src/ 
data/ 
Makefile 

В моем коде я использовать относительные пути к моим данным. Итак, «../data/xml/xmlFile.xml». Это хорошо, если бы я выполнения двоичный файл из бен/папки:

[email protected]:~/PATH-TO-PROJECT/bin$ ./binary-file 
argv[0] = ./binary-file 
dirname(argv[0]) = . 

Но если бы я выполнения двоичного файла из основной папки (или любую другую папку, а не бен/папки):

[email protected]:~/PATH-TO-PROJECT$ bin/binary-file 
argv[0] = bin/binary-file 
dirname(argv[0]) = bin 

Файлы xml не найдены, потому что «../data» теперь будет перемещаться вверх по одному каталогу из основной папки (или любой другой папки, в которой вы находитесь при выполнении программы).

Как я могу сделать так, чтобы бинарный файл мог быть выполнен из любого каталога в моей системе?

Для того, чтобы вопрос немного более ясно:

[email protected]:~/cpp-workspace/sdl-projects/sdl-space-shooter/bin$ ~/cpp-workspace/sdl-projects/sdl-space-shooter/bin/SpaceShooter 
argv[0] = /home/brandonto/cpp-workspace/sdl-projects/sdl-space-shooter/bin/SpaceShooter 
dirname(argv[0]) = /home/brandonto/cpp-workspace/sdl-projects/sdl-space-shooter/bin 

[email protected]:~/cpp-workspace/sdl-projects/sdl-space-shooter/bin$ cd .. 
[email protected]:~/cpp-workspace/sdl-projects/sdl-space-shooter$ ~/cpp-workspace/sdl-projects/sdl-space-shooter/bin/SpaceShooter 
argv[0] = /home/brandonto/cpp-workspace/sdl-projects/sdl-space-shooter/bin/SpaceShooter 
dirname(argv[0]) = /home/brandonto/cpp-workspace/sdl-projects/sdl-space-shooter/bin 
Unable to load image ../data/graphics/background/darkPurple.png! SDL_image Error: Couldn't open ../data/graphics/background/darkPurple.png 
Unable to load image ../data/graphics/sprites/meteorBrown_big1.png! SDL_image Error: Couldn't open ../data/graphics/sprites/meteorBrown_big1.png 

Здесь я выполнил двоичный файл, как только внутри бен/папки, а затем один раз внутри основной папки. Бинарный файл отлично работал изнутри bin/folder, но не смог найти относительные пути к файлам .png изнутри основной папки.

+0

Вам нужно добавить сниффера для исполняемого файла, чтобы выяснить, где он находится. Обычно это означает чтение arg [0] (первоначальный вызов) и, возможно, проверку некоторых путей поиска. – Jiminion

+0

Вы должны иметь возможность находить папку bin, независимо от того, где вызывается исполняемый файл. – Jiminion

+0

Вы писали 'SpaceShooter' самостоятельно? Если нет, как насчет написания сценария оболочки, который изменяется в папку «bin» и запускает «SpaceShooter»? – lurker

ответ

2

Возможно, вы задаете неправильный вопрос: система сборки не имеет никакого отношения к выполнению программы.

Однако, если вы ищете ответ, как заставить мою программу правильно использовать данные, расположенные относительно установки программы, чем это ответ.

Когда вы программируете main, он получает двоичный путь в качестве первого параметра (индекс 0). Этот путь может быть относительным или абсолютным, но в любом случае он позволяет найти каталог .

Это также полезные ссылки:

Вот как вы можете использовать первый аргумент:

#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; 
} 
+0

Спасибо! Это сработало. Я хотел бы добавить, что если вы выполняете сам каталог/bin /, то argv [0] = '.' который является краевым случаем, о котором вы должны заботиться, если вы используете этот метод. – brandonto

0

Я считаю, что вы можете найти свой идентификатор процесса (pid) с помощью команды getpid и выполнить функции для извлечения каталога способом, подобным this question на Ask Ubuntu.

+0

Я думаю, что это излишне. Есть более простые способы сделать это, включая pwd и arg [0]. – Jiminion

+0

Pwd может лгать вам ... особенно если вызывается из другого каталога. – ojblass

+0

Вам не нужен pwd. Просто arg [0] и путь поиска. – Jiminion

0

У меня были бы данные, связанные каким-то образом (организационно) с каталогом bin, в котором находится исполняемый файл.

Затем при запуске подпрограммы, если предоставляется полный путь (отмечено проверкой arg [0]), вы можете найти каталог данных. Если предоставлен относительный путь, затем последовательно найдите путь поиска до тех пор, пока не найдете исполняемый файл, а затем вы можете найти каталог данных.

Не требуется никаких расходов. (Я думаю, именно так Python находит свой путь или, по крайней мере, как это было сделано.)

0

Я обычно решить эту проблему с помощью установки программы , В старые добрые времена я бы установил эти настройки в файле .ini, который будет сопровождать исполняемый файл. Некоторые настройки будут настраиваться изнутри программы, и все они могут быть отредактированы с помощью текстового редактора. Если файл отсутствует или любой параметр отсутствует, они будут созданы по умолчанию.

Для определения местоположения данных программы я бы использовал ее полное абсолютное имя пути. Например, это может быть

Datapath = D:\os50k 

и программа затем при необходимости добавляет отдельные имена файлов на путь.

В эти дни в Windows для этой цели используется системный реестр. Однако ваш вопрос помечен Linux, который хранит настройки в разных местах, включая каталог программы.

This question и this question описывают процесс более полно.

Смежные вопросы