I need to load some text (shader code) from a file that is placed next to my library file. This way, I can #include TextureBloomer.h in several projects, and TextureBloomer will take care of loading its shader without needing to set paths through configuration or environment variables. The directory hierarchy looks like this:
libs/libName/src/TextureBloomer/TextureBloomer.{h,cpp}
libs/libName/src/TextureBloomer/shaders/shader_name.{frag,vert}
apps/mine/appName/src/[several .h files that #include "TextureBloomer/TextureBloomer.h"]
I’ve been looking around for ways to do this, but all I found was posts saying “you can’t”, or “why would you even want to do that?” I found a (hacky) solution that works for me, but I’ve seen other posts that say using __FILE__ is bad juju (with no justification). So, the question is a) what’s so bad about this, and b) is there a way to improve it, eg. so I don’t have to have “TextureBloomer.cpp” in the source file in case I change its name.
string filename ("shaders/shader_name.frag");
string currentFile (__FILE__);
currentFile.replace(currentFile.find("TextureBloomer.cpp"), 18, "");
file.open((currentFile + filename).c_str());
EDIT:
I’m on OSX, compiling with XCode. I only really need it to work there, but other *nixes wouldn’t hurt.
You are using that file as sort of a “resource” of your program. A simple option is in these cases to generate automatically a .cpp module that contains the source you need as string literals… i.e. if your source code is for example
you generate a .cpp that contains
This generation requires only a few lines of say Python code and can be probably added to your project makefile so that in case anything changes in the original source the file is regenerated automatically.
Doing this way you will end up with an executable that will include this resource internally and there will be no need to distribute an external file.
If on the other hand you need that file to be changed by the user without recompiling the program then an external file is the only option, but how to find a directory where it is located is highly system dependent. Just consider for example that on certain systems it’s perfectly possible to delete the file of a program that is currently in execution… in this case there is no directory on any disk where the program is currently residing.
The reason that there is no way in C++ to portably access the source code directories at runtime is because the C++ language clearly separate the two phases of “compile time” and “run time” even at a philosophical level.