In a project using GNU Autotools, is there a task to launch xgettext? - gettext

Summary :
I have a project using GNU Autotools. I have a pot file. I need to update it. Is there a magical "make" task that run xgettext for me (I'm lazy ?)
Verbose version :
Hi
I am trying to setup a project using GNU autotools and gettext.
I'm trying to follow the 'lazy' path (that is, only writing configure.ac, Makefile.am, and such, and let tools generate the rest for me as much as possible).
I used gettextize once on my package, so I got a package.pot file created, and I derived a fr.po file (I'm trying to translate in french).
I never managed to get my code translated, but I figured out it might be because the code was not in the proper place. The translated string is in a lib instead of a main, and the documentation is quite unclear about what I must do in this case. If my main call a function in a lib, and the function from the lib is using _(). Should I use gettext of dgettext in this case ? My lib is just here for organisation purpose, so I'm okay with using the same domain (only one package.pot file for the whole app).
So, to try something simpler, I moved my string to the main (it's really just a hello world, for the moment). So I need to update the package.pot file, at least, to realize that the string position changed, need I ? In this case, would I use xgettext manually (painfully passing it the list of all interesting cpp files, which will be a pain in the ass when I have more than one file), or is there a 'make whatever' task somewhere that I can run ?
This may look stupid, but I've not been able to find it.
Also, any help on finding why my code is not translated, (anything not in http://www.gnu.org/software/gettext/FAQ.html#integrating_noop) is welcome !
Thanks
PH

Ok, it turns out that :
there is a update-po task in the generated Makefile of the po/ folder, that does just what I want ;
this tasks looks to file referenced in the POTFILES.in file, which I had forgotten to update.
So it was something stupid.

Related

MPI Autocompletion in Visual Studio Code

I'm trying to use Visual Studio Code to develop Fortran MPI programs. However, while I can successfully build and run them just fine, it would be very helpful for me if I can use intellisense/autocompletion features for MPI (as well as other external modules). I have /usr/lib/openmpi/ (which contains mpi_f08.mod) as part of fortran.includePaths in my settings.json. However, when I use mpi_f08, I get the problem message from VS Code Module "mpi_f08" not found in project. Here is a minimal CMake build example:
! hello.f90
program hello
use mpi_f08
implicit none
integer :: ierror, nproc, my_rank
call MPI_Init()
call MPI_Comm_size(MPI_COMM_WORLD, nproc, ierror)
call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierror)
print*, "hello from rank ", my_rank
call MPI_Finalize()
end program hello
# CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project(hello_mpi)
enable_language(Fortran)
find_package(MPI REQUIRED)
add_executable(hello_mpi hello.f90)
include_directories(${MPI_Fortran_INCLUDE_PATH})
target_link_libraries(hello_mpi PUBLIC ${MPI_Fortran_LIBRARIES})
I would like to be able to (i) get rid of the warning/message and more importantly (ii) enable suggestions from MPI when I press CTRL+space as it would if I was calling from an internal module.
I'll post a partial answer since it's better than nothing, hopefully this helps someone else and/or enables someone else to answer my question fully.
It seems the issue relates to the Fortran language server, which can be configured by adding a .fortls JSON file, as explained on its Github README: https://github.com/hansec/fortran-language-server
I added the following, which allowed it to find not only local modules but also MPI (and the external module json-fortran):
{
"source_dirs": ["src", "."],
"ext_source_dirs": [
"/path/to/json-fortran/src",
"/path/to/openmpi-4.1.2/ompi/mpi/fortran/use-mpi-f08",
]
}
This doesn't capture all functions in json-fortran, which I think is because of its .inc files, as it doesn't give me function pointers like json_file::get at autocomplete.
As for MPI, this kind of works, as it gives me all the functions I can think of needing, but with _f08 appended to the end of it. I don't know the inner workings of OpenMPI but I guess e.g. MPI_Init wraps MPI_Init_f08 for reasons of backward compatibility. For now I can simply autocomplete to the _f08 version and remove that bit manually. (I also tried adding openmpi-4.1.2/ompi/mpi/fortran/use-mpi-tkr and openmpi-4.1.2/ompi/mpi/fortran/mpif.h but no luck).
Would be nice to get this detail sorted though. It is also mildly annoying that I must manually include the source dirs now (removing it makes it not find local modules).

How to tell MakeMaker to add exactly the libraries I want?

I'm using XS to create a Perl Module which uses a C library.
For testing purposes, I've created a test library which has two simple functions:
void kzA() (does a simple printf)
void kzB(int i, char *str) (does a printf of the received parameters)
I've also created some glue in XS, in order, for now, to access the kzA() function:
(I'm only showing the function itself, but the includes are there, too, in the XS)
void
ka()
CODE:
printf("Before kzA()\n");
kzA();
printf("After kzA()\n");
So, I compiled the test library as fc.so, and it is in the same directory as my xs file, and my Makefile.PL (/workspace/LirePivots)
In my Makefile.PL, I set the LIBS key to ['-L/workspace/LirePivots -l:fc.so'], but when executing it with perl (perl Makefile.PL), it says "Warning (mostly harmless): No library found for -l:fc.so"
It then writes a Makefile which does NOT mention said library. And then, after compiling (with "make") and installing (with "sudo make install"), when I run my test script which calls the ka() function from my module, I get the line "before", but the kzA() function isn't called, obviously, because it cannot find the kzA symbol, and the program stops there.
Creating a C test program which I would link with the very same arguments (-l:fc.so -L/workspace/LirePivots) does work, and, as long as I put the path in LD_LIBRARY_PATH, it finds the function and runs it correctly.
I also tried renaming the library libfc.so, and changing the -l part to "-lfc", but it didn't work either. It never manages to find the library.
Does anyone know what I do wrong ?
EDIT:
As requested, I created a minimum example: https://github.com/kzwix/xsTest
To run it, you'll need to have a Linux with Perl 5, along with XS (package perl-devel, on Redhat). And a C compiler, and make, obviously.
Ok, I still don't know the reason why it wouldn't find the library. But I found a workaround:
By adding the test library as "libfc.so" to /usr/lib, then running "sudo ldconfig", the library got added to the cache (when named fc.so, even if in /usr/lib, ldconfig would not add it. Also, it wouldn't work with symbolic links, either, I had to really copy it there).
After the library got added to the cache, "perl Makefile.PL" would still not find the library. I had to use "-L/usr/lib" in addition to "-lfc" for it to at long last find the library, and "agree" to add the parameters to the link step of the library.
After this happened, I could compile with "make", and executing the test program did work as originally intended (I saw both the "before" and "after" printf, and I saw the one from the function in the kzA() function from libfc.so)
Thanks Håkon Hægland for helping.
(I can't provide the Dockerfiles, they link to images internal to my organization, which I'm not allowed to share)

How do I execute classes in Puppet

I just started using puppet. I don't know how to execute classes in puppet.
I've my files "config.pp init.pp install.pp service.pp".
For example install.pp :
class sshd::install{ ... }
Next, i declare my class in init.pp with "include sshd::install".
I also tried to run classes with :
class{'sshd::install':} -> class{'sshd::config':} ~> class{'sshd::service':}
After that, i launch "puppet apply init.pp" but nothing.
My scripts work individualy, but with classes i don't know how to execute all my classes.
Thanks
I'm not sure how much research you've done into Puppet and how its code is structured, but these may help:
Module Fundamentals
Digital Ocean's guide.
It appears that you are starting out with a basic module structure (based on your use of init/install/service), which is good, however your execution approach is that of a direct manifest (Not the module itself) which won't work within the module you are testing due to autoloading unless your files are inside a valid module path.
Basically: You want to put your class/module structured code within Puppet's module path (puppet config print modulepath) then you want to use another manifest file (.pp) to include your class.
An example file structure:
/etc/puppetlabs/code/modules/sshd/manifests/init.pp
install.pp
service.pp
/tmp/my_manifest.pp
Your class sshd(){ ... } code goes in the init.pp, and class sshd::install(){ ... } goes in install.pp etc...
Then the 'my_manifest.pp' would look something like this:
include ::sshd
And you would apply with: puppet apply /tmp/my_manifest.pp.
Once this works, you can learn about the various approaches to applying manifests to your nodes (direct, like this, using an ENC, using a site.pp, etc... Feel free to do further reading).
Alternatively, as long as the module is within your modulepath (as mentioned above) you could simply do puppet apply -e 'include ::sshd'
In order to get the code that you have to operate the way you are expecting it to, it would need to look like this:
# Note: This is BAD code, do not reproduce/use
class sshd() {
class{'sshd::install':} ->
class{'sshd::config':} ~>
class{'sshd::service':}
}
include sshd
or something similar, which entirely breaks how the module structure works. (In fact, that code will not work without the module in the correct path and will display some VERY odd behavior if executed directly. Do not write code like that.)

Fay: include another Fay file?

I have one Fay file which is the heart of my program, however I need some helpers for my logic, for instance a method to replace substrings. From what I understand, if I need such methods which are offered by many Haskell libraries from Hackage directly, I can't use those Haskell libraries, but I must copy-paste the code in my project. So it's what I did, I copy-pasted a "replace" function together with other helpers from the MissingH library in a new file in my project: Utils.hs.
That Utils.hs compiles without problems with Fay. Also I import it in my main Fay file and I get a JS file for the main project file without problems. However at runtime I get the following error:
ReferenceError: Utils$$36$ is not defined
I don't think that Fay will include the code from the helper file in my main JS file, so I'm including both JS files in the loading HTML. And to make even more sure that when I load the main file, that the utils file is loaded, I load it like that:
$.getScript("Utils.js", function(){
$.getScript("FayConfig.js");
});
But despite this I still get the error. I tried compiling the Utils.hs with "--library" but it didn't help.
So my question is, which setup do I need to achieve that the generated JS will find the helper functions that I put in another HS file, knowing that at compile-time, Fay (apparently) finds them without problems? Is there an example of such a setup online? Most of the Fay uses that I found have all the code in a single HS file, though they often use external Fay code from cabal, as with fay-jquery. In my case, setting up a cabal project just for these simple helpers would be overkill.
Which version of Fay are you using (fay --version)? It seems like you are using a version older than
0.16 where forgetting import Prelude wouldn't give any warnings, see this closed ticket. So upgrade fay and/or add import Prelude.
We're also considering renaming operators in the produced output to make error messages like these easier to understand.
You do not need to invoke fay several times, fay outputs all dependencies into the same js file. So there's no difference from using a cabal package in that regard.
Hope this helps, otherwise please give me a way to reproduce this.

Gwt i18n > generating properties files

I'm using GWT in my stuff, and I would like to make it,
international, so I use GWT constants method.
I have a java file with defaults, and I now need to make properties files.
In a remember, there is a special thing to do (or done automagically) to generate
a kind of template where all constants are generated with empty labels for other langages.
Did I dream this ?
(using eclipse indigo to develop webapp with gwt but not gae)
[edit:]
this was not a dream, it's i18ncreator:
http://code.google.com/intl/fr-FR/webtoolkit/doc/latest/RefCommandLineTools.html#i18nCreator
but I can't make it working on windows :-(
[edit again ]
due to this issue : http://code.google.com/p/google-web-toolkit/issues/detail?id=5113
recommended solution is use i18ncreator in gwt 1.7 (!)
you should see the page on locales in GWT
I had the same issue. I was looking all over the place for the answer but could not find an answer; either in the docs or on stackoverflow.
So I asked in the GWT gitter channel and was told to use the compiler argument
-extra <destination-folder-name>
to generate the .properties files from the Interface files.
Steps in eclipse:
Select project you want to compile
[right click] -> Google -> GWT Compile
In the window that opens, open the Advanded options.
Add the following additional compiler argument -extra <destination-folder-name>
Compile
This should generate the *.properties files in the /destination-folder-name.
NOTE: This only generates the .properties files. It does not actually compile the application with all the locales for deploy.
Move the MyInterfaceExtension_*.properties to be right beside the MyInterfaceExtension.java file.
Make copies for each locale i.e. MyInterfaceExtension_fr_CA.properties, MyInterfaceExtension_fr_FR.properties, etc..
Translate them
Then run the compilation process again with out the -extra <destination-folder-name> option. Because it is not needed anymore.
This will compile with all the locales you enabled. You can now deploy the app the usual way.
Quick Tips:
When compiling for the first time in order to generate the .properties file, I commented out the locales in the module definition file so that the compiler will not sit there and compile again and again for every browser and every locale
i.e. supported_browser_count x enabled_locale_count = 5 browsers x 3 locales = 15 compilation Permutations, which is going to increase your compilation time.
Because, all I needed was that one *_en.properties file.
For the second compilation, after you copied and translated the properties files for each locale, you have to enable all the locales you want to support and compile.
Credits:
github #niloc132 : Colin Alworth
github #ibaca : Ignacio Baca Moreno-Torres
For helping me with this.
For my project, I used the i18n-Creator
http://code.google.com/webtoolkit/doc/latest/DevGuideI18n.html#DevGuidePropertiesFiles
It kind of does the opposite of what you are asking for. With the i18n-creator, you create the properties files for the various locales and run the script that is generated with the i18n-creator, and it will generate the constants interface.
I haven't heard yet of this feature in Eclipse but IntelliJ IDEA has this feature, you just create the Constants Interface class and the properties file. If you add a method in the class file it will warn you to add the property or the other way around. HTH.