How do I get my executable's location using Fortran?
I have a program written in Fortran 90/95; after invocation it always reads a certain data file. For the users' convenience I'd like them to just have to place this file in the same directory as the executable itself, without making them set some environment 开发者_运维技巧variable/extend $PATH, and without forcing them to use a certain directory for that purpose. The program should 'simply' look for the file in the directory in which it itself is stored, NOT in the directory from which it is run. So far, however, I have failed to find a solution to this problem. I tried using
getarg(0,path)
but that only gave me whatever string I had used to invoke the program, not its absolute path.
If you have any suggestions, also concerning workarounds, please don't hesitate to reply. Thanks a lot in advance!
Requiring that the binary is in some specific directory strikes me as weird. As long as the binary is found on the PATH, stuff should work. What you can do instead is to try to read the data file from the current working directory, i.e. the directory the user is in when launching the program.
I you don't want to require users to always copy the data file around you could search a few "default" places and then use the first one where the file is found, e.g. the current working directory, then $HOME/.your_program/file.dat, and finally /usr/local/share/your_program_name/file.dat, or something like that.
Edit If you, however, wish to continue down this wrongheaded path, at least on Linux you can use readlink() (you probably need to create a C wrapper for this, see the ISO C BINDING in recent Fortran compilers) to check the /proc/self/exe symlink.
As an aside, GETARG is not part of the Fortran standard, so you're relying on a vendor extension (which admittedly is quite widely supported). As of Fortran 2003, the standard feature for doing this is the GET_COMMAND_ARGUMENT intrinsic.
I think this is a difficult problem to solve in fortran, and I think you're right in your approach (putting the data file in the same directory as the executable). Fortran needs something along the lines of python's
os.path.dirname(os.path.realpath(sys.argv[0]))
Unfortunately, fortran is absolutely terrible for I/O and your question highlights just one small facet.
Just in case someone else jumps the gun and thinks this is a trivial question - consider the case where you don't know the OS that people are going to run this executable on, and you don't know the executable's name.
My, probably awful, workaround is to use INDEX to look for "/". If it returns nonzero then the user "must" be on a linux system, so use INDEX to strip away the executable's name and you've got your path. Then look for "\", and if INDEX finds something then assume OS=windows
and strip away the executable.
canavanin, have you found a solution in the meantime? In g77 getarg(0,path)
delivers the executable with the full path, but not in gfortran. However, this shortcoming of gfortran seems to be windows specific only. See Here which demonstrates getarg's functioning in a bash shell...
---corection: I have found out now that the problem is not GFORTRAN vs G77, it's the specific build. The most recent GCC / GFORTRAN version (4.54) of the DJGPP (DOS port) distribution makes the getarg(0,path) deliver the full path in front of the [executable].exe. The separation character is "/" not "\".
In Digital Visual Fortran (etc.), in Windows, I do it like this:
SUBROUTINE GetFullExeName(FULLNAME,L)
!******************************************************************************
!
! Gets the full name of the current executing program.
!
!******************************************************************************
USE DFWIN
CHARACTER*(*) FULLNAME ! full name
INTEGER L ! length
L= GetModuleFileName(NULL,FULLNAME,LEN(FULLNAME)) ! windows API
FULLNAME(L+1:) = ' '
END
精彩评论