Access Path Of File In C++ - c++

I want to access the path of the executable file. I know in python, you can do the following:
import os
filePath, fileName = os.path.split(__file__)
The code above will get the path of the file, and the name of the file that the lines are in. Is this applicable in C++ (returning the name is more optional)? I do NOT want the source code, only the path of the executable.
PS: if you think this is very little detail, copy paste the code above, paste the following:
print(filePath)
and run the code in a python intepreter.
PPS: Tried installing POCO or qt, as one of the comments in the first question mentioned, and didn't find out how to install.
PPPS: For more details of why I want the path and what I'm doing it with: I need the path so I can load assets to a game. Sometimes, the program just won't load the image after putting in the name of the file, like other people in tutorials do (albeit the image file is in the same directory). And then I figured out that for python, the code above works, so I'm asking if this is applicable in C++.

In Python, you're getting the path to the file containing the source code that's executing.
In C++, the file containing the source code to what's executing may not exist, or (more often) may exist but be inaccessible (e.g., stored on a system to which you don't have access).
Instead, in C++ the source code is normally compiled to an executable file, and that's what runs. But that executable contains machine-level instructions rather than the C++ source code of the program as the programmer wrote it.
If you want access to the source code at run time, you're almost certainly going to have to do that on your own--make sure a copy of the source code is on the target computer in some location you can find.
The C++ standard library contains basic support for things like searching for a particular file in a file system tree, but it's going to be up to you to put those building blocks together into a system that gives you access to the source code at run-time. Chances are pretty good that in the process, you'll end up needing a few things that are available on most operating systems, but still require code specific to the operating system you're using (e.g., getting the path to the executable file so you can build some path relative to that where you store the source file).

Related

how to designate the working directory at run time in C++ in basis of cross platform?

I am confused how I can designate the working directory of "./" at run time.
So sometimes it will be the directory of the project file, sometimes it is the directory of the executable. All dependents how you execute the program.
How should I designate this working directory "./" as I want it always be? I mean I want to keep it always the directory of the executable for example.
And this implementation should be platform independent.(I think it will be rather big hard, so you can ignore this if it's not possible).
If you have a compiler that supports the filesystem Technical Specification or a C++17 compiler you can use the new soon-to-be standard filesystem library
However I don't know of a catch-all way to discover the executable directory. One way that I think should work on Windows and Linux is to use argv[0] which contains the launch command and find its canonical path:
std::error_code ec;
// find the executable directory
auto exe_folder = fs::canonical(fs::path(argv[0]), ec).parent_path();
// set the current directory to the executable directory
fs::current_path(exe_folder);
Currently GCC v6 has filesystem as the Technical Specification otherwise you can also use boost::filesystem on-which it is based.
Typically programs don't have write permissions to the directory that contains the executable.
myself found a solution if anyone else is interested. you have to have Qt on your computer at first.
you can change the working directory at run time with:
QDir::setCurrent(qApp->applicationDirPath());
This will change the working directory at run time to that of the executable.
But it does not look very neat cause you have to have Qt.
The best solution I've come up with (without requiring a C++17 compiler) is if you can guarantee a data-driven file is going to reside next to your executable, you can place a similarly named file in your project directory.
"./[your file].txt" is always going to exist, and you can use the content of these files as an indicator of where your current working directory is.

Adding a text file to an exe generated by PyInstaller

I have a rather interesting problem I've been trying to find a way to solve, and as of the moment, I have not found a solution to. I currently have built a GUI program using Python, and more specifically using Tkinter, which will generate a file with a list of commands to be repeated by my program in the specified order while waiting however long is specified. It's basically used to create a macro, which is recorded in a file and can be ran later using another function in the program.
What I would like to add to my program is a manner in which to create an .exe file, which is a standalone file, that can run a script from within it. The reason I can not find a good way to do this though is because I need for it to be created on the fly. What I was thinking I'd like to do is generate an .exe(Standalone macro exe) with PyInstaller ahead of time, and package this in to my main .exe also using PyInstaller. When you choose the option to create a standalone macro, it would proceed to get the .exe(Standalone macro exe) which I had packaged in to my main .exe from the directory in which it was unpacked in to when the program was run, copy it to the desired location for the standalone exe to be saved to, and then copy the script the user wished to be run as a standalone and package it in to the standalone exe.
I have no idea how to go about this, because I'm not sure exactly how PyInstaller puts the files in to a .exe when it packages it. Because of that, I wouldn't know how to add a file to an existing .exe using python.
Basically what I need help with is how I might go about adding a text file to an .exe generated by PyInstaller.
Ummm,
Could you clarify something...are you thinking something like Perl's (25th birthday today) (camel book by Larry Wall, p44) handles or a Bash HERE document ?
Update (based on discussion below): This will integrate python files and other externalities into a single installable:
http://www.pyinstaller.org/export/d3398dd79b68901ae1edd761f3fe0f4ff19cfb1a/project/doc/Manual.html?format=raw#create-a-spec-file-for-your-project
http://www.pyinstaller.org/export/d3398dd79b68901ae1edd761f3fe0f4ff19cfb1a/project/doc/images/SE_exe.png

g++: Use ZIP files as input

We have the Boost library in our side. It consists of a huge number of files which never change and only a tiny portion of it is used. We swap the whole boost directory if we are changing versions. Currently we have the Boost sources in our SVN, file by file which makes the checkout operations very slow, especially on Windows.
It would be nice if there were a notation / plugin to address C++ files inside ZIP files, something like:
// #ZIPFS ASSIGN 'boost' 'boost.zip/boost'
#include <boost/smart_ptr/shared_ptr.hpp>
Are there any support for compiler hooks in g++? Are there any effort regarding ZIP support? Other ideas?
I assume that make or a similar buildsystem is involved in the process of building your software. I'd put the zip file in the repository, and add a rule to the Makefile to extract it before the actual build starts.
For example, suppose your zip file is in the source tree at "external/boost.zip", and it shall be extracted to "external/boost", and it contains at its toplevel a file "boost_version.h".
# external/Makefile
unpack_boost: boost/boost_version.h
boost/boost_version.h: boost.zip
unzip $<
I don't know the exact syntax of the unzip call, ask your manpage about this.
Then in other Makefiles, you can let your source files depend on the unpack_boost target in order to have make unpack Boost before a source file is compiled.
# src/Makefile (excerpt)
unpack_boost:
make -C ../external unpack_boost
source_file.cpp: unpack_boost
If you're using a Makefile generator (or an entirely different buildsystem), please check the documentation for these programs for how to create something like the custom target unpack_boost. For example, in CMake, you can use the add_custom_command directive.
The fine print: The boost/boost_version.h file is not strictly necessary for the Makefile to work. You could just put the unzip command into the unpack_boost target, but then the target would effectively be phony, that is: it would be executed during each build. The file inbetween (which of course you need to replace by a file which is actually present in the zip archive) ensures that unzip only runs if necessary.
A year ago I was in the same position as you. We kept our source in SVN and, even worse, included boost in the same repository (same branch) as our own code. Trying to work on multiple branches was impossible, as it would take most of a day to check-out a fresh working copy. Moving boost into a separate vendor repository helped, but it would still take hours to check-out.
I switched the team over to git. To give you an idea of how much better it is than SVN, I have just created a repository containing the boost 1.45.0 release, then cloned it over the network. (Cloning copies all of the repository history, which in this case is a single commit, and creates a working copy.)
That clone took six minutes.
In the first six seconds a compressed copy of the repository was copied to my machine. The rest of the time was spent writing all of those tiny files.
I heartily recommend that you try git. The learning curve is steep, but I doubt you'll get much pre-compiler hacking done in the time it would take to clone a copy of boost.
We've been facing similar issues in our company. Managing boost versions in build environments is never going to be easy. With 10+ developers, all coding on their own system(s), you will need some kind of automation.
First, I don't think it's good idea to store copies of big libraries like boost in SVN or any SCM system for that matter, that's not what those systems are designed for, except if you plan to modify code in boost yourself. But let's assume you're not doing that.
Here's how we manage it now, after trying lots of different methods, this works best for us.
For every version of boost that we use, we put the whole tree (unzipped) on a file server and we add extra subdirectories, one for each architecture/compiler-combination, where we put the compiled libraries.
We keep copies of these trees on every build system and in the global system environment we add variables like:
BOOST_1_48=C:\boost\1.48 # Windows environment var
or
BOOST_1_48=/usr/local/boost/1.48 # Linux environment var, e.g. in /etc/profile.d/boost.sh
This directory contains the boost tree (boost/*.hpp) and the added precompiled libs (e.g. lib/win/x64/msvc2010/libboost_system*.lib, ...)
All build configurations (vs solutions, vs property files, gnu makefiles, ...) define an internal variable, importing the environment vars, like:
BOOSTROOT=$(BOOST_1_48) # e.g. in a Makefile, or an included Makefile
and further build rules all use the BOOSTROOT setting for defining include paths and library search paths, e.g.
CXXFLAGS += -I$(BOOSTROOT)
LFLAGS += -L$(BOOSTROOT)/lib/linux/x64/ubuntu/precise
LFLAGS += -lboost_date_time
The reason for keeping local copies of boost is compilation speed. It takes up quite a bit of disk space, especially the compiled libs, but storage is cheap and a developer losing lots of time compiling code is not. Plus, this only needs to be copied once.
The reason for using global environment vars is that build configurations are transferrable from one system to another, and can thus be safely checked in to your SCM system.
To smoothen things a bit, we've developed a little tool that takes care of the copying and setting the global environment. With a CLI, this can even be included in the build process.
Different working environments mean different rules and cultures, but believe me, we've tried lots of things and finally, we decided to define some kind of convention. Maybe ours can inspire you...
This is something you would not do in g++, because any other application that wants to do it would also have to be modified.
Store the files on a compressed filesystem. Then every application gets the benefit automatically.
It should be possible in an OS to allow transparent access to files inside a ZIP file. I know that I put it in the design of my own OS a long time ago (2004 or so) but never got it to a point where it was usable. The downside is that seeking backwards in a file inside a ZIP is slower as it's compressed (and you can't rewind the compressor state, so you have to seek from the start instead). This also makes using a zip-inside-a-zip slow for rewinding and reading. Fortunately, most cases just read a file sequentially.
It should also be retrofittable to current OSes, at least in client space. You can hook the filesystem access functions used (fopen, open, ...) and add a set of virtual file descriptors that your own software would return for a given filename. If it's a real file just pass it on, if it's not open the underlying file (possibly again via this very function) and pass a virtual handle. When accessing the file contents, read directly from the zip file without caching.
On Linux you would use an LD_PRELOAD to inject it into existing software (at usage time), on Windows you can hook the system calls or inject a DLL into the space of software to hook the same functions.
Does anybody know if this already exists? I can't see any clear reason it wouldn't...

How to check if path leads to executable file?

I try to create some kind of file browser. I want to know if file under path is executable in a cross-platform way.
How to do such thing with boost::filesystem?
Boost doesn't have stuff about permissions, because POSIX permissions are not "crossplatform".
Use the platform-specific APIs at your disposal as required. Sorry!
You can try QT. It is cross-platform. You do not have to care about the operating system differences while dealing with files. What you mean by "executable" is somehow unclear though. If you are talking about file permissions, OT can give this kind of information (Just look at QFile class documentation). If you want to learn whether you can actually run it or not, you have to have some kind of file extension convention. For example, .exe in Windows. I do not know, may be there is a way to look at the initial bits of the file and learn whether it is a binary or not, but I think you will not be able to find a library call for that. You have to implement some platform specific routines for this. If I am not mistaken, file browsers mostly look at the extension of the file to find out the type. For example, if you change the file extension of a pdf to exe than windows explorer sees this file as an executable. Clearly after the file type assumption, it can try to learn some other things about the file, such as icon of the executable. But initially it only looks at the extension. Otherwise, it would be very slow to browse directories containing large numbers of files.
I hope, I gave some relevant information here

Compile batch file into an EXE file

I want to compile a batch file into an EXE file using C++. I can get through parsing the batch file and writing a new .cpp file. But I don't know how to compile the new .cpp file into an EXE file for the end user.
OK, here's the thing, I am creating an application in DevC++ that will read in a batch file. Then, one by one parsing it using:
system(getline(myfile,line));
After setting everything up, I save the newly created file as "main.cpp".
The problem is, I want to compile it into an EXE file, from my program, for the end user.
So basically, can I compile a C++ file from a C++ EXE?
Yes, you can provided that the end user has a C++ compiler installed and you're emitting valid C++.
Depending on the compiler you're using, your C++ executable would have to spawn a process that runs
cl main.cpp
or a similar invocation of the compiler after finishing the translation.
If your user doesn't have a compiler installed, then you're pretty much out of luck - trying to build a C++ compiler yourself is a rather non-trivial exercise.
The short answer is no. Unless you are willing to write an entire C++ compiler, you will need to invoke an external C++ compiler to compile that .cpp file.
On the plus side, if you are simply looking to convert .BAT files into .EXE files, there are several existing solutions, such as quickbfc.
Can I ask why do you need to parse bat file?
I mean if you are taking input or something from that file then can you try to use a database or something for that?
Also for the user end you can write web application to display output.
There`s C++ Server Pages equivalent to JSP, PHP which can use C++ classes.
Am I helping here or this is not what you want? may be if you can describe you application use somebody can help you better.