Compile .qm (i18n) files into binary - c++

I have multiple i18n qm files and translation works like a charm right now.
The problem I'm facing is, that I have the following folder structure:
project
-build
--debug
--release
-src
-i18n
Now my colleagues have different build folder structures, hence:
translator.load("../../i18n/{translationfile}");
won't work for them.
One solution might be to settle on a specific build-folder structure, but this is not what I want. I'd prefer to export all the translations to the application itself so it may be shipped without any special folder structure. Just give the customer the binary and go, like it should be.
Anyway, I have no idea how to do this in qmake (nor in cmake for that matter, but qmake is what I need to use here.)
I had a look at: How to Integrate Qt4 qm files into binary using cmake and QRC? but still not sure.
Any help appreciated.

Looks like I fixed it.
Instead of
translator.load("../../i18n/{translationfile}");
I use
QDir dir(":/i18n");
translator.load(dir.absoluteFilePath({translationFile}));
I also added a i18n.qrc file to my pro file:
RESOURCES += images.qrc \
i18n.qrc
It works if I move the binary/executable to another folder and execute it from there, so I guess that's all that is needed to compile translation files into a QApplication.

Related

How can I make a C++ program to read predefined files after installation on linux

My project folder has the following structure
-Project/
/src
-Main.cpp
-MyReader.cpp
/headers
-MyReader.h
/DataFiles
-File.dat
-File1.dat
My class Object.cpp has a couple of methods which reads from File.dat and File1.dat and parse the information to Map objects. My problem is that I am using Autotools (in which I'm very very newbie) for generating config and installer files and I don't know how to make all the DataFiles files accessible for the program after installation. The program doesn't work properly because of the code fails when trying to read those files through relative paths. Locally, the program runs perfectly after executing in terminal make && ./program.
How can I solve this issue? Thanks in advance for your help!
A platform independent way to do this with Autotools is using the $(datadir) variable to locate the system data directory and work relative to that.
So in your Makefile.am file you can create a name like this:
myprog_infodir = $(datadir)/myprog
# Set a macro for your code to use
myprog_CXXFLAGS = -DDATA_LOCATION=\"$(datadir)/myprog\"
# This will install it from the development directories
myprog_info_DATA = $(top_srcdir)/DataFiles/File.dat $(top_srcdir)/DataFiles/File1.dat
# make sure it gets in the installation package
extra_DIST = $(top_srcdir)/DataFiles/File.dat $(top_srcdir)/DataFiles/File1.dat
Then in your program you should be able to refer to the data like this:
std::ifstream ifs(DATA_LOCATION "/File.dat");
Disclaimer: Untested code
I figured out one method and will give my example here:
In my Makefile.am
AM_CPPFLAGS = -D MATRIXDIR="\"$(pkgdatadir)/matrix\""
nobase_dist_pkgdata_DATA = matrix/AAcode.txt \
matrix/BLOSUM50 matrix/BLOSUM70.50 matrix/BLOSUM100 matrix/BLOSUM50.50 \
matrix/BLOSUM75 matrix/BLOSUM100.50 matrix/BLOSUM55 matrix/BLOSUM75.50 \
... more not shown
I put quite some number of datafiles in the matrix directory, just show a few of them. In my source file, I simply use the macro MATRIXDIR:
scorematrix.cpp:string MatrixScoreMethod::default_path=MATRIXDIR;
This seems to work well for me. You can use other versions of the data automake variable, such as dist_data_DATA instead of pkgdata. It is a good idea to use pkgdata this way your data will not be mixed with other packages. The nobase_ is to tell automake not to strip the matrix directory during install. Those escaped double quotes seems to be needed for string type so that you don't get compiler errors.

How to run a makefile that takes in all header files within a subdirectory

I'm extremely confused over how to make in c++. I'm working on a school project where we downloaded several files -- some starter code, and some libraries. File structure is something along the lines of
main --- lib/ severalLibraryFolders
\--- src/ starterCode
I cannot seem to get the starter code to make within the command line. There's a vector library within one of the library folders and when I run make on the starter file (a .cpp and .h) I get a fatal error: 'vector.h' not found. I managed to use gcc and the -I flag to include the folder that vector.h was in which fixed it -- however other similar problems popped up even after I used the -I flag on all possible library folders.
I'm fairly certain I'm doing something wrong/need a makefile but all the examples I've found are not clear on how to do what I need to do, which is essentially to find all header files below the parent directory. I'd love some direction here, as I come from a more scripty background where this sort of thing is much easier!

Add source to an existing automake program

I would like to edit an existing software to add a new source file (Source.cpp).
But, I can't manage the compilation process (it seems to be automake and it looks very complicated).
The software (iperf 2: https://sourceforge.net/projects/iperf2/files/?source=navbar) is compiled using a classical ./configure make then make install.
If I just add the file to the corresponding source and include directory, I got this error message:
Settings.cpp:(.text+0x969) : undefined reference to ...
It looks like the makefile isn't able to produce the output file associated with my new source file (Source.cpp). So, I probably need to indicate it manually somewhere.
I searched a bit in the project files and it seemed that the file to edit was: "Makefile.am".
I added my source to the variable iperf_SOURCES in that file but it didn't workded.
Could you help me to find the file where I need to indicate my new source file (it seems a pretty standard compilation scheme but I never used automake softwares and this one seems very complicated).
Thank you in advance
This project is built with the autotools, as you already figured out.
The makefiles are built by automake. It takes its input in files that usually have a am file name extension.
The iperf program is built by the makefile generated from src/Makefile.am. This is indicated by:
bin_PROGRAMS = iperf
All (actually this is a simplification, but which holds in this case) source files of a to be built binary are in the corresponding name_SOURCES variable, thus in this case iperf_SOURCES. Just add your source file to the end of that list, like so (keeping their formatting):
iperf_SOURCES = \
Client.cpp \
# lines omitted
tcp_window_size.c \
my_new_file.c
Now, to reflect this change in any future generated src/Makefile you need to run automake. This will modify src/Makefile.in, which is a template that is used by config.sub at the end of configure to generate the actual makefile.
Running automake can happen in various ways:
If you already have makefiles that were generated after an configure these should take care of rebuilding themselves. This seems to fail sometimes though!
You could run automake (in the top level directory) by hand. I've never done this, as there is the better solution to...
Run autoreconf --install (possibly add --force to the arguments) in the top level directory. This will regenerate the entire build system, calling all needed programs such as autoheader, autoconf and of course automake. This is my favorite solution.
The later two options require calling configure again, IMO ideally doing an out of source built:
# in top level dir
mkdir build
cd build
../configure # arguments
make # should now also compile and link your new source file

Keeping all libraries in the Arduino sketch directory

I know that you are supposed to place any external libraries under the "libraries" folder of the arduino install directory, but I have a project that uses several libraries that I have created for the project and mainly to keep all that code self contained and out of the main pde file. However, I have tried to place the libraries in the same directory as the main PDE file so that I can more easily keep everything synced up in subversion (I work on this on multiple computers) and I don't want to have to keep going back and syncing up the libraries separately. Also, just for the sake of being able to easily zip of the sketch folder and know that it contains everything it needs.
I've tried adding the header files to the sketch as a new tab, but that doesn't seem to work at all... don't even care if they should up in the arduino IDE.
I've also tried adding the libraries to the sketch directory in subdirectories (what I would greatly prefer) and then linking to them as:
#include "mylib/mylib.h"
and
#include <mylib/mylib.h>
But both of these result in file not found errors.
Is this possible? And, if so, how do I include them in the main file for building? Preferably in their own subdirectories.
I had the same issue. Solved it for Arduino IDE > 1.8. Seems a specialty in newer IDEs (?) according to the reference (see bottom link).
You have to add a "src" Subdirectory before creating a library folder. So essentially your project should look like this:
/SketchDir (with *.ino file)
/SketchDir/src
/SketchDir/src/yourLib (with .h and .cpp file)
and finally in your sketch you reference:
#include "src/yourLib/yourLib.h"
otherwise in my case - if I am missing the "src" folder - I get the error message that it cannot find the yourLib.cpp file.
Note: I am using a windows system in case it differs and actually VS Code as wrapper for Arduino IDE. But both IDE compile it with this structure.
References:
https://forum.arduino.cc/index.php?topic=445230.0
For the sketches I have, the "*.h" and "*.cpp" library files actually reside in the same folder as the sketch, and I call them like "someheader.h". I also noticed that if I go into sketch menu and add file... that the file doesn't appear until I close and reopen the sketch.
I agree with you; this is an intolerable way to develop software: it requires every file that you need to be in the same directory as the main program!
To get around this, I use make to put together a single .h file from my .h and .cpp sources - you can see this used in this Makefile:
PREPROCESS=gcc -E -C -x c -iquote ./src
# -E : Stop after preprocessing.
# -C : Don't discard comments.
# -x c : Treat the file as C code.
# -iquote ./src : Use ./src for the non-system include path.
TARGETS=sketches/morse/morse.h
all: $(TARGETS)
clean:
rm $(TARGETS)
%.h: %.h.in
$(PREPROCESS) $< -o $#
Arduino is very picky about file endings - if you put a .cpp or .cc file in its directory it automatically uses it in the source, and you can't include anything that's not a .cpp, .cc or .h - so this is about the only way to do it.
I use a similar trick also to put together JavaScript files here.
This requires that you run make after editing your files, but since I'm using an external editor (Emacs) anyway, this is zero hassle for me.
Unfortunately the Arduino IDE is awful and shows no signs of improving. There is no real build system so it only lets you build programs that reside in a single directory.
The only real solution is to write a makefile, then you can use a real IDE. I'm hopeful that one day someone will write an Arduino plugin for QtCreator.
Here's an example makefile:
http://volker.top.geek.nz/arduino/Makefile-Arduino-v1.8
I just had this same problem (I also like to keep the code self-contained), so I'll just jot down some notes; say I have a MyPdeSketch.pde using MyLibClass.cpp; then I have it organized like this
/path/to/skdir/MyPdeSketch/MyPdeSketch.pde
/path/to/skdir/MyPdeSketch/MyLibClass/MyLibClass.cpp
/path/to/skdir/MyPdeSketch/MyLibClass/MyLibClass.h
(In principle, /path/to/skdir/ here is equivalent to ~/sketchbook/)
What worked for me is something like:
mkdir /path/to/arduino-0022/libraries/MyLibClass
ln -s /path/to/skdir/MyPdeSketch/MyLibClass/MyLibClass.* /path/to/arduino-0022/libraries/MyLibClass/
After restart of the IDE, MyLibClass should show under ''Sketch/Import Library''.
Note that the only way I can see so far for a library class file to refer to other library files is to include them relatively (from 'current location'), assuming they are all in the same main arduino-0022/libraries folder (possibly related Stack Overflow question: Is it possible to include a library from another library using the Arduino IDE?).
Otherwise, it should also be possible to symlink the MyLibClass directory directly into arduino-0022/libraries (instead of manually making a directory, and then symlinking the files). For the same reason, symlinking to the alternate location ~/sketchbook/libraries could also be problematic.
Finally, a possibly better organization could be:
/path/to/skdir/MyLibClass/MyLibClass.cpp
/path/to/skdir/MyLibClass/MyLibClass.h
/path/to/skdir/MyLibClass/MyPdeSketch/MyPdeSketch.pde
... which, after symlinking to libraries, would force MyPdeSketch to show under the examples for the MyLibClass library in Arduino IDE (however, it may not be applicable if you want to self-contain multiple class folders under a single directory).
EDIT: or just use a Makefile - which would work directly with avr-gcc, bypassing the Arduino IDE (in which case, the sketchbook file organization can be somewhat loosened)..
Think I know what do u need exactly.
you have a project folder say MYPROJ_FOLDER and you want to include a Libraries folder that contains more children folders for your custom libraries.
you need to do the following:
1- create folders as follows:
-MyProjFolder
-MyProjFolder/MyProjFolder
and then create a file with the folder name in .ino extension
-MyProjFolder/MyProjFolder/MyProjFolder.ino
2- create libraries folder:
-MyProjFolder/libraries <<<<< name is not an option should be called like that.
3- then create your own libraries
-MyProjFolder/libraries/lib1
-MyProjFolder/libraries/lib1/lib1.cpp
-MyProjFolder/libraries/lib1/examples <<<< this is a folder
-MyProjFolder/libraries/lib1/examples/example1
repeat step 3 as much as you want
also check http://arduino.cc/en/Guide/Libraries
I did it a little differently. Here is my setup.
Visually this is the directory layout
~/Arduino/Testy_app/ <- sketch dir
/Testy_app.ino <- has a #include "foo.h"
/foo <- a git repo
/foo/foo.h
/foo/foo.cpp
Here is how I build:
~/Arduino/Testy_App/$ arduino-cli compile --library "/home/davis/Arduino/Testy_app/foo/" --fqbn arduino:samd:mkrwan1310 Testy_app
If you wish to be more elaborate and specify libs and src dirs, this also works
~/Arduino/Testy_app/ <- sketch dir
/Testy_app.ino <- has a #include "foo.h"
/lib <- a git repo
/lib/foo/src/foo.h
/lib/foo/src/foo.cpp
and the build method is:
~/Arduino/Testy_App/$ arduino-cli compile --library "/home/davis/Arduino/Testy_app/lib/foo/src" --fqbn arduino:samd:mkrwan1310 Testy_app
One more bit of tweaking needs to be done to include files from the lib dirs to main dir. If you need to do that, this is the work around:
~/Arduino/Testy_app/ <- sketch dir
/Testy_app.ino <- has a #include
"foo.h"
/inc/Testy_app.h
/foo <- a git repo
/foo/foo.h
/foo/foo.cpp < has a "include testy_app.h"
Then do the compile like this
~/Arduino/Testy_App/$ arduino-cli compile \
--library "/home/davis/Arduino/Testy_app/inc" \
--library "/home/davis/Arduino/Testy_app/foo/src" \
--fqbn arduino:samd:mkrwan1310 Testy_app
What has worked for me is to create a dir, for example "src" under the sketch dir, and under that a dir for each personal library.
Example:
I have a project called ObstacleRobot, under that a folder for my sketch, named obstaclerobot (automatically created by the IDE) and there my sketch "obstacleRobot.ino"
Up to now we have:
/ObstacleRobot
/obstaclerobot
obstacleRobot.ino
Then I wanted to include a personal library that was fully related with this project and made no sense in including it in the IDE libraries, well in fact I want to do this for each part of the robot but I'm still working on it.
What in the end worked for me was:
/ObstacleRobot
/obstaclerobot
obstacleRobot.ino
/src
/Sonar
Sonar.h
Sonar.cpp
Then what you have to do in the main sketch is to write the include as follows:
#include "src/Sonar/Sonar.h"
And thats all.
Following the lines of Hefny, make your project an example for your library.
For example (Unix env), let's say the libraries are in ~arduino/libraries
Your create your project ~arduino/libraries/MyProject, your libraries go there (for example ~/arduino/libraries/MyProject/module1.h ~/arduino/libraries/MyProject/module1.cpp ~/arduino/libraries/MyProject/module2.h ~/arduino/libraries/MyProject/module2.cpp
Now:
mkdir -p ~arduino/libraries/MyProject/examples/myproj
edit ~arduino/libraries/MyProject/examples/myproj/myproj.ino
(note that this is not examples/myproj.ino but examples/myproj/myproj.ino)
Restart the IDE, you should find your project in the menu File/Example/MyProject.
Also note that you do the include with #include
Why dont we just write a script with a single copy command, copying our libs from wherever our library is located into the arduino IDE library folder?
This way we keep the file structure we want and use the IDE library requirements without fuss.
Something like this works for me:
cp -r mylibs/* ~/Documents/programs/arduino-1.5.8/libraries/.
Note that the paths are relative to my own file structure.
Hope this helps someone. This includes my future self that I bet will be reading this in a near future... as usual!
J

Compiling C++Builder project on command line

Is there a way to compile a C++Builder project (a specific build configuration) from the command line?
Something like:
CommandToBuild ProjectNameToBuild BuildConfiguration ...
There are different ways for automating your builds in C++Builder (as of my experience, I'm speaking about old C++Builder versions like 5 and 6).
You can manually call compilers - bcc32.exe (also dcc32.exe, brcc32.exe and tasm32.exe if you have to compile Delphi units, resource files or assembly language lines of code in your sources) and linker - ilink32.exe.
In this case, you will need to manually provide the necessary input files, paths, and keys as arguments for each stage of compilation and linking.
All data necessary for compilation and linking is stored in project files and, hopefully there are special utilities, included in the C++Builder installation, which can automate this dirty work, provide necessary parameters to compilers and linker and run them. Their names are bpr2mak.exe and make.exe.
First you have to run bpr2mak.exe, passing your project *.bpr or *.bpk file as a parameter and then you will get a special *.mak file as output, which you can use to feed on make.exe, which finally will build your project.
Look at this simple cmd script:
#bpr2mak.exe YourProject.bpr
#ren YourProject.mak makefile
#make.exe
You can provide the real name of "YourProject.mak" as a parameter to make.exe, but the most straightforward way is to rename the *.mak file to "makefile", and then make.exe will find it.
To have different build options, you can do the following:
The first way: you can open your project in the IDE, edit options and save it with a different project name in the same folder (usually there are two project files for debug and release compile options). Then you can provide your building script with different *.bpr files. This way, it looks simple, because it doesn't involves scripting, but the user will have to manually maintain coherency of all project files if something changes (forms or units added and so on).
The second way is to make a script which edits the project file or make file. You will have to parse files, find compiler and linker related lines and put in the necessary keys. You can do it even in a cmd script, but surely a specialised scripting language like Python is preferable.
Use:
msbuild project.cbproj /p:config=[build configuration]
More specifics can be found in Building a Project Using an MSBuild Command.
A little detail not mentioned.
Suppose you have external dependencies and that the .dll file does not initially exist in your folder
You will need to include the external dependencies in the ILINK32.CFG file.
This file is usually in the folder
C:\Program Files (x86)\Borland\CBuilder6\Bin\ilink32.cfg
(consider your installation location)
In this file, place the note for your dependencies.
Example: A dependency for TeeChart, would look like this (consider the last parameter):
-L"C:\Program Files (x86)\Borland\CBuilder6\lib";"C:\Program Files (x86)\Borland\CBuilder6\lib\obj";"C:\Program Files (x86)\Borland\CBuilder6\lib\release";"C:\Program Files (x86)\Steema Software\TeeChart 805 for Builder 6\Builder6\Include\";"C:\Program Files (x86)\Steema Software\TeeChart 805 for Builder 6\Builder6\Lib\"
You will also need to include the -f command to compile.
In cmd, do:
//first generate the file.mak
1 - bpr2mak.exe MyProject.bpr
//then compile the .mak
2 - make.exe -f MyProject.mak
You can also generate a temporary mak file with another name, as the answer above says, directly with bpr2mak
bpr2mak.exe MyProject.bpr -oMyTempMak.mak