Hello now i try translate project on other platform(first platform it's windows, now company planed use Linux platform), i use eclipse in windows and Linux, language is c++. Name project PostLib and he have next structure: PostLib/common, PostLib/inc, PostLib/inc_ext, PostLib/src.
PostLib/common its part for control memory leaks and for smart pointer. PostLib/inc PostLib/inc_ext - this part for header, and PostLib/src for sources code.My problem next: In project settings, i use PostLib/common, PostLib/inc and PostLib/inc_ext, and Eclipse write error: File Def.h(PostLib/inc_ext) can not find file p_mem.h(PostLib/common). How can it be?
When i look property all direction in project i saw interesting thing: Property on directory PostLib/inc_ext difference than all project, on other directory property same like in project/ Property i mean Property->Settings->GCC C++ Compiler->Directories, i try add path (PostLib/common) , but no effect, Eclipse write error File Def.h(PostLib/inc_ext) can not find file p_mem.h(PostLib/common).
On Linux systems directory separator is /, not \!
PostLib\common\p_mem.h is a path in windows, but is not in Linux. The equivalent for Linux is PostLib/common/p_mem.h.
Also, filesystem paths on Linux are case sensitive. p_mem.h is a different file from P_Mem.h: be sure you used the right characters for files and directories.
Related
I'm trying to use the png++ library. Already added it to the library search path in eclipse (windows user, if relevant), but I get the
fatal error: png++/png.hpp: No such file or directory
I really don't know what to do.
Thank you!
Okay. You need to check your settings one by one.
It (png++) is a C++ library, so you must have C++ compiler set in your
run/debug settings.
Add your library include folder to that compiler's settings
To actually link to the library, you need to add the .lib/.a files or DLLs to linker settings.
I'm not much of a user of Eclipse CDT but that's how it works. If you are trying to do image manipulation without prior C++ experience, I suggest you to go with python/Java, they are easy to use.
After days, tears and blood, my professor (PhD Daniel Brake) figured it out! Here is what we did to make it work. I hope you never need to use this library on a Windows machine (conf: Windows 10, MinGW, Eclipse):
Make sure that you have the MinGW installation manager, have all the packages on the basic setup installed, and in "all packages", look for "msys-zlib", class dll
Now open the cmd (Windows+x, A, to open in admin mode)
You have to open the "msys.bat", go to C:\MinGW\msys\1.0\msys.bat
It will open a unix-like terminal, then type:
mingw-get install libz-dev
cd /path/to/libpng/folder
./configure -prefix=/mingw
make
make install
Google png++, download it, and using the MinGW terminal go to the folder that contains it:
cd /path/to/png++/folder
tar -zxf png++-0.2.x.tar.gz -C
In the png++ page, go to http://savannah.nongnu.org/bugs/?46312 and donwnload the file to the png++ folder
Replace the error.hpp file
Using a text editor, open the error.hpp file you just downloaded
Add #include <sstream> to the includes
look for the part and comment it:
strerror_r(errnum, buf, ERRBUF_SIZE);
return std::string(buf);
Now, add this in the same block of above:
std::stringstream ss;
ss << errnum;
return ss.str();
Save and close
Now, open Eclipse, create the project for the png++
Go to Configuration > C/C++ Build > set Configuration to "Debug [Active]"
Then C/C++ Build > Settings > GCC C++ compiler, add to "Include paths (-l)", the path to the folder png++ and the path to the folder that contains the file png.h, in my case it's in "C:\MinGW\msys\1.0\mingw\include"
Go to MinGW C++ Linker > Libraries, add to "Libraries (-l)" just the word "png" and in the "Library seach path (-L)" the path to the folder of libpng.a, in my case, "C:\MinGW\msys\1.0\mingw\lib"
save
to use it, in the header, add #include <png.hpp> (not #include <png++/png.hpp>)
it will have a warning, you can ignore it
it doesn't works!
in your MinGW terminal, go to the folder that have the "eclipse.exe" and open the Eclipse that way (don't ask me, my professor said something about path, I have no idea why)
Maybe you can simply use another compiler, but I couldn't, or use Linux.
I've been using windows in a class I've been taking but I am trying to run a basic code to figure out how to open/close/input/output from files on Xcode and the code I usually use on visual studios isn't working any idea why? thanks!
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream fin;
ofstream fout;
string input;
fin.open("inputFile.txt");
if(fin.fail())
cout << "File failed to open." << endl;
fin >> input;
fout.open("outputFile.txt");
fout << input;
}
Put your .txt files in the same directory where your main.cpp file is (or anywhere you like).
In Xcode go to Product > Scheme > Edit Scheme > Run (on the left) > Options (middle top)
Down under Options for "Working Directory" check “Use custom working directory” and set it to the directory where you .txt files are located.
To work with the files, you will have to specify just file names, e.g. in_file.open("inputFile.txt"); no path is necessary.
Here's a completely different approach: Have Xcode copy the input file for you.
Select your project in Xcode
Select Build Phases
Click the '+' button to create a new Build Phase
Select New Copy Files Build Phase
Select Products Directory
Click the '+' button to add your file
Click Add Other
Select your input file and click Open
Check the Copy items… checkbox and click Finish
Now every time you build your project, the input file will be copied to the same folder as the executable no matter where it is built. Of course, to see the output file, you'll still need to find the executable in Finder.
The answers don't really explain the problem so I thought I'd do that.
When you pass a relative path like "inputFile.txt" to file APIs, it's treated as relative to the working directory when the program is executed. This is the same as the 'working directory' when you use cmd.exe or Terminal.app or command lines in general. The Unix command pwd ("print working directory") displays the current working directory. On Windows running the command cd with no arguments performs the same function. (On Unix running cd with no arguments will change the working directory to the user's home directory.)
When you run a program from the command line, the command line shell sets the program's working directory. When you run a program from within an IDE, the IDE sets the working directory. Since, unlike on a command line, there's no obvious answer for what the IDE should set as the working directory, Visual Studio and Xcode set the working directory to different locations by default: Visual Studio sets the working directory to $(ProjectDir), the directory containing the Visual Studio project file; Xcode sets the working directory to the build products directory, i.e. the location the executable was written to.
Some possible solutions to your problem are:
Do not use a relative path, and therefore don't depend on the working directory. This isn't much help in making the program more portable, because the absolute paths will also differ between platforms, and so you will still have to 'configure' the program for each platform. In fact using an absolute path is worse, because it means your source code must differ, whereas it would be better to keep that difference confined to each platform's build configuration.
Configure the IDE to use your desired working directory. Visual Studio can be configured by right clicking the project, selecting Configuration Properties > Debugging > Working Directory, and setting the working directory to the desired path (potentially using Visual Studio build variables).
nepete's answer describes how to configure the working directly set by Xcode.
Configure the IDE's build process to copy your data files to an appropriate location. In Visual Studio you would do this in a C++ project by configuring the project's Properties > Configuration Properties > Build Events.
SSteve's answer covers how to configure additional build steps in Xcode.
I'm guessing you have inputFile.txt in the folder that contains your source code. That's not going to work. You need to put it in the folder that contains the generated executable. To find that folder, right-click on your app under Products and select Show In Finder.
This image shows what it looks like for a command line program. It also shows the Finder window that was opened. As you can see, it is a different folder than the one containing the source code.
As suggested by nepete, edit the scheme, but use $PROJECT_DIR as the custom working directory. Helps with moving the project around, or working in two different environments (e.g., home and office).
BTW. $PROJECT_DIR is one of the Xcode Environment Variables, and also helps with passing file names as command line arguments to programs (settable under "Arguments" in the scheme).
I've struggled with the same problem today. I wanted to add C code to my Swift project and my file pointer was always NULL.
Unfortunately, in XCode 9 for iOS app, I couldn't change the working directory. Changing Build phases didn't help me either. After 4+ hours of trial and error, that's what I've come up with finally and it works:
when copying files to XCode, I've chosen "Create groups", but I needed to choose "Create folder references":
I created a new objective-c file (.m) and copied all my C code there.
I left untouched .h files (XCode generated bridging header and my own .h file with public functions declaration). Now my project structure looked like this:
In my dict.m file in place of previous plain c fopen part:
FILE *dic = fopen("dictionary.txt", "r");
I added obj-C code:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"dictionary" ofType:#"txt"];
FILE *dic = fopen([filePath cStringUsingEncoding: NSUTF8StringEncoding], "r");
And it works now without any problem! It's just amazing!
ps I decided to write this answer in case it will help someone like me and will save them some time. If you know how to change working directory in XCode 9 for iOS, please, leave me a comment - now I am really curious why I can't find it.
I've been using Eclipse for a while and this has me stymied. I created a library name ITS8410_LIB a few weeks ago and then let it sit while I worked on a supporting library called Reach_Lib. The directory include paths I added back when I first created the project work fine. Today I finished Reach_Lib and went to add its path to ITS8410_Lib. I used the project properties C++ settings to add a workspace path (like I've done many times before). I have only one build configuration. The path is shown in the image (the one highlighted in blue is the specific one I'm talking about in this question).
When I go to include the file in the source neither Eclipse (I see the yellow question mark) nor the compiler (I get a compiler error) can locate the file. If I add the a directory path using the full absolute path syntax the results are the same. I can modify the source code and specify the #include via a full relative path from the current directory, and it is found. Eclipse just won't use the path specified in the project settings. This same Reach_Lib has an associated unit test project and the path is specified with a workspace setting from there and it works fine.
Directory paths that were added before today appear fine. Paths (there are two libs showing this behavior) I add today just seem to be ignored. I took a look at the compiler settings (see image below) and the path specified to the compiler appears to be OK.
Running under Windows7 64 bit (but using a 32 bit version of Eclipse Indigo).
I have tried:
rebuilding indices
Exiting and restarting Eclipse multiple times
workspace and absolute file paths
modifying the order of the include paths
different .h include files in project
Update
I took a look into the .cproject file and while I don't know much about what these files are supposed to look like I think I have a problem. Maybe the question is: How do I tell Eclipse to rebuild the .cproject file? I appear to have two similar sections and Eclipse is getting confused. I can see different version numbers tagged as suffixes. It appears to me that the visual editors are letting me modify one section but the IDE and compiler only care about the other section. Here's the relevant portions
...
<folderInfo id="nbeclipse.toolchain.nbl.rel.396284009." name="/" resourcePath="">
<toolChain id="nbeclipse.toolchain.nbl.rel.tc.1465290409" name="NetBurner Device Library" superClass="nbeclipse.toolchain.nbl.rel.tc">
<targetPlatform id="nbeclipse.toolchain.nbl.rel.tc.targetPlatform.283367649" isAbstract="false" name="NetBurner Module Library" superClass="nbeclipse.toolchain.nbl.rel.tc.targetPlatform"/>
<builder buildPath="${workspace_loc:/ITS8410_Lib/Release}" id="nbeclipse.toolchain.nbl.rel.tc.builder.2064025940" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Release ELF builder (MINGW)" superClass="nbeclipse.toolchain.nbl.rel.tc.builder"/>
<tool id="nbeclipse.toolchain.nbl.rel.tc.gcc.278195048" name="GNU C Compiler" superClass="nbeclipse.toolchain.nbl.rel.tc.gcc">
<inputType id="nbeclipse.toolchain.nbl.rel.tc.gcc.input.1060035859" name="GNU C Input" superClass="nbeclipse.toolchain.nbl.rel.tc.gcc.input"/>
</tool>
<tool id="nbeclipse.toolchain.nbl.rel.tc.gpp.767008127" name="GNU C++ Compiler" superClass="nbeclipse.toolchain.nbl.rel.tc.gpp">
<option id="nbeclipse.toolchain.super.gcc.directories.includepaths.1666029541" name="Include paths (-I)" superClass="nbeclipse.toolchain.super.gcc.directories.includepaths" valueType="includePath">
**inside here is an option list with all my include paths**
...
</folderInfo>
Then right after the folderInfo close tag another folderInfo section starts
<folderInfo id="nbeclipse.toolchain.nbl.rel.396284009.2022231003" name="/" resourcePath="src">
<toolChain id="nbeclipse.toolchain.nbl.rel.tc.1982112905" name="NetBurner Device Library" superClass="nbeclipse.toolchain.nbl.rel.tc" unusedChildren="">
<targetPlatform id="nbeclipse.toolchain.nbl.rel.tc.targetPlatform" isAbstract="false" name="NetBurner Module Library" superClass="nbeclipse.toolchain.nbl.rel.tc.targetPlatform"/>
<tool id="nbeclipse.toolchain.nbl.rel.tc.gcc.1671008421" name="GNU C Compiler" superClass="nbeclipse.toolchain.nbl.rel.tc.gcc.278195048">
<inputType id="nbeclipse.toolchain.nbl.rel.tc.gcc.input.436341699" name="GNU C Input" superClass="nbeclipse.toolchain.nbl.rel.tc.gcc.input"/>
</tool>
<tool id="nbeclipse.toolchain.nbl.rel.tc.gpp.498310867" name="GNU C++ Compiler" superClass="nbeclipse.toolchain.nbl.rel.tc.gpp.767008127">
**the newly added paths don't show up here, if I add them manually things start working**
The key to the answer was posted by dbrank0 but he didn't promote it to an answer so I just upvoted the comment. Something went wrong in the .cproject file and editing it manually fixed the problem.
Try to replace relative workspace path to real path (add same include as filesystem) in include directories project settings.
full absolute path is okay at any time.
when use the relative directory you should be careful.
in eclipse the current directory is not the same as run directory.
string strRunDir, strCurDir;
strRunDir = AfxGetApp()->m_pszExeName;
strCurDir = GetCurrentDirectory(...);
and strRunDir != strCurDir;
when you want to use the relative directory, you should reference to the runDir;
C++ How to get a filename (and path) of the executing .so module in Unix?
Something similar to GetModuleFileName on Windows.
Although it is not a POSIX standard interface, the dladdr() function is available on many systems including Linux, Solaris, Darwin/Mac OS X, FreeBSD, HP-UX, and IRIX. This function takes an address, which could be a pointer to a static function within the module for example (if cast to void *), and fills in a Dl_info structure with information including the path name of the shared object containing that address (in the dli_fname member).
Unfortunately, there is no way to do that using UNIX or POSIX. If you need to use it to look up some sort of data, you should use the $PATH environment variable and search for the data in a path that is relative to each entry in $PATH. For example, it is not uncommon to store binaries in "installdir/bin" for some installation directory "installdir" and to store the associated data in "installdir/share/name_of_program" for some installation directory and some program named "name_of_program". If that is the case, then looking at "../share/name_of_program/name_of_resource_file" relative to each entry in getenv("PATH") is a good way of searching for resources. Another thing you could do is allow the necessary information to be provided on the commandline or in some configuration file, and only perform the search if needed as a fallback option.
Edit
Now that you've stated your rationale for this, I would advise you to simply use the QSettings class from Qt for your configuration information, as it uses the preferred native mechanism for each platform (the registry on Windows, a PLIST file on Mac OS X, the Gnome GConf database on Linux). You may want to take a look at my C++ Project Template as it uses Qt to do just this, and it provides simple commandline options to easily tweak the configuration settings ("--prefset", "--prefget", and "--preflist" manipulate QSettings).
That said, if you absolutely must use an XML configuration file of your own instead of using the preferred native mechanism, I strongly advise you to place the system-wide configuration in "installdir/etc" while placing your library in "installdir/lib" for some installation directory "installdir", as that is the typical place for configuration files on UNIX systems, and "installdir/lib" should ONLY be used for library files, not for configuration files and other errata. I suggest you place a user-specific version of the configuration file in "$XDG_CONFIG_HOME" (if it is defined) or in "$HOME/.config" (where "$HOME" is the user's home folder).
When searching for the system-wide configuration file, I would recommend that you search within $XDG_CONFIG_DIRS if it is defined; if it isn't defined, then falling back to "/etc/xdg" or searching for "../etc/name_of_your_program.conf.xml" relative to "$PATH" and possibly also relative to the "$LD_LIBRARY_PATH", "$DYLD_LIBRARY_PATH", "$DYLD_FALLBACK_LIBRARY_PATH"), the contents of "/etc/ld.so.conf" if it exists, and the contents of "/etc/ld.so.conf.d/*.conf" if those files exist, halting your search as soon as you encounter the first valid such configuration file would be a sensible approach.
Credit goes to Roger for pointing out the XDG Basedir Spec and for his excellent constructive criticisms.
Possible solutions:
You can read the /proc/{PID}/mmap file for the list of shared libraries. Where {PID} is the process pid (you can get it using getpid()).
Call the command line tool ldd for the program binary file (stored in argv[0]).
If you write a solution from scratch take a look of ldd commands source code from uClibc how to get the list of shared libs from an elf binary.
Do any C++ GNU standalone classes exist which handle paths cross platform? My applications build on Windows and LInux. Our configuration files refer to another file in a seperate directory. I'd like to be able to read the path for the other configuration file into a class which would work on both Linux or Windows.
Which class would offer the smallest footprint to translate paths to use on either system? Thanks
Unless you're using absolute paths, there's no need to translate at all - Windows automatically converts forward slashes into backslashes, so if you use relative paths with forward slash path separators, you'll be golden. You should really avoid absolute paths if at all possible.
try boost::filesystem
Filesystem library in boost will probably help you.
There are many ways, IMHO the correct answer is to redesign your program to avoid manipulating paths. I posted an answer here: https://stackoverflow.com/a/40980510/2345997 which is relevant.
ways:
Add a command line option which allows a user to specify the path in question instead of reading it from a config file.
Add a command line option so that the user can specify a base path. Paths in the config file will be interpreted as located under this base path.
Split your config file into three. One file will have cross platform configuration, another file will have windows only configuration and a final file will have Linux only configuration. Then the user can specify the correct path for both Windows and Linux. On windows your program will read the cross-platform config file and the windows only config file. On Linux it will read the cross-platform file and the Linux only config file.
Add preprocessing to your config file parsing. This will allow you to have one config file where the user can make your program ignore some of the lines in the file depending on which OS the program is running on. Therefore, the user will be able to specify the path to the file twice. Once for Linux, and once for Windows.
Change the design so that the files are always located in the same directory as your executable - then the user only specifies file names in the config file rather than paths to files.
Use a simple function that switches "/" to "\". Then document to the user that they must specify paths as Linux paths and this transformation will be applied for windows.
Create your own path mini-language for this and document it to the user. E.g: "/" - specifies a directory separator, {root} - expands to the root of the filesystem, {cwd} - expands to the current directory, {app} - expands to the path to your application etc... Then the user can specify file paths like: {root}/myfiles/bob.txt on both platforms.
Some paths will work on both platforms. E.g: relative paths like ../my files/bill.txt. Restrict your application to only work with these paths. Document this limitation and how your application handles paths to the user.