1

Problem

I am currently trying to install NIST's sclite, which is part of SCTK 2.4.0 (github or newer version). I am attempting the install on Cygwin in bash. The installation is done using make.

I was able to get past an issue with file [format] not recognized by doing a 64-bit compilation, as described at the end of the README and as explained in detail in another of my SO posts.

Now, I again follow the installation instructions and get the following error after typing make all

In file included from main.cpp:20:0:
recording.h:122:36: error: template argument 2 is invalid
         map<string, Filter::Filter*> filters;
                                    ^
recording.h:122:36: error: template argument 4 is invalid
make[3]: *** [makefile:59: main.o] Error 1
make[3]: Leaving directory 
'/cygdrive/c/Me/programs/nist/sctk/src/asclite/core'
make[2]: *** [makefile:12: all] Error 2
make[2]: Leaving directory 
'/cygdrive/c/Me/programs/nist/sctk/src/asclite'
make[1]: *** [makefile:12: all] Error 2
make[1]: Leaving directory '/cygdrive/c/Me/programs/nist/sctk/src'
make: *** [makefile:20: all] Error 2

Does anyone know what I can do to complete the install?

Note: When the question here is answered, the install doesn't actually complete on Cygwin. There are things to do before and after, which I'm posting on SO with my progress and with questions on where to go next.


My Attempts

I haven't found anything about Filter in C++ docs, and a search through the files in the cloned directory ( $ find . -type f \( -name "*.h" -o -name "*.c" -o -name "*.cpp" \) -print0 | xargs -I'{}' -0 grep -Hn "Filter" {} ) gives, in part:

./src/asclite/core/checker.h:26:class Checker : public Filter
./src/asclite/core/filter.cpp:19: * Abstract interface to a Filter.
./src/asclite/core/filter.cpp:25:Filter::Filter()
./src/asclite/core/filter.cpp:30:Filter::~Filter()
./src/asclite/core/filter.h:26: * Abstract interface to a Filter.
./src/asclite/core/filter.h:28:class Filter
./src/asclite/core/filter.h:32:         Filter();
./src/asclite/core/filter.h:34:         virtual ~Filter();

...

Which, as far as I can tell, means that there is a constructor, Filter in the namespace, Filter.

Here's the "code part" of filter.cpp

$ cat src/asclite/core/filter.cpp | tail -16

/**
 * Abstract interface to a Filter.
 */

#include "filter.h" // class's header file

// class constructor
Filter::Filter()
{
}

// class destructor
Filter::~Filter()
{
}

Here's the code part for filter.h

$ cat src/asclite/core/filter.h | tail -27

#ifndef FILTER_H
#define FILTER_H

#include "stdinc.h"
#include "speech.h"
#include "speechset.h"

/**
 * Abstract interface to a Filter.
 */
class Filter
{
        public:
                // class constructor
                Filter();
                // class destructor
                virtual ~Filter();

                virtual bool isProcessAllSpeechSet() = 0;
                virtual unsigned long int ProcessSingleSpeech(Speech* speech) = 0;
                virtual unsigned long int ProcessSpeechSet(SpeechSet* ref, map<string, SpeechSet*> &hyp) = 0;

                virtual void LoadFile(const string& filename) = 0;
};

#endif // FILTER_H

System Details

$ uname -a
CYGWIN_NT-6.1 CAP-D-ENG-INT3 2.10.0(0.325/5/3) 2018-02-02 15:16 x86_64 Cygwin
$ bash --version
GNU bash, version 4.4.12(3)-release (x86_64-unknown-cygwin) ...
$ gcc --version
gcc (GCC) 6.4.0 ...
$ g++ --version
g++ (GCC) 6.4.0 ...
$ make --version
GNU Make 4.2.1
Built for x86_64-unknown-cygwin ...
$ systeminfo | sed -n 's/^OS\ *//p'
Name:                   Microsoft Windows 7 Enterprise
Version:                6.1.7601 Service Pack 1 Build 7601
Manufacturer:           Microsoft Corporation
Configuration:          Member Workstation
Build Type:             Multiprocessor Free
bballdave025
  • 1,347
  • 1
  • 15
  • 28
  • There is a way that I think is easier. Basically, you install the `tools` part of [kaldi](http://kaldi-asr.org/). You can also install the `src` part and use it if you want (unless you're on Cygwin under Windows 7 as I am, in which case there are more problems.) If you just want the `sclite` stuff, copy `/path/to/kaldi/tools/sctk-2.4.10/*` to a place that's not inside the kaldi tree. I did `mkdir $HOME/sctk-2.4.10 && cp /path/to/kaldi/tools/sctk-2.4.10/* $HOME/sctk2.4.10/` . I'll probably elaborate later. Then you can `rm -rf /path/to/kaldi` . – bballdave025 Jun 06 '18 at 21:57
  • Note that the fixes described here and in the other solutions to which I've linked ([link1](https://stackoverflow.com/q/50278663/6505499), [link3](https://stackoverflow.com/q/50283077/6505499)) are also needed if one uses a more current version of `sclite` available at jaguar.ncsl.nist.gov/pub/sctk-2.4.10-20151007-1312Z.tar.bz2 – bballdave025 Jun 06 '18 at 21:59
  • That more-current-version link might change, so here's the hosting site: [https://www.nist.gov/itl/iad/mig/tools](https://www.nist.gov/itl/iad/mig/tools) – bballdave025 Jul 16 '18 at 17:28

1 Answers1

0

The My Answer

(Also look at my comment under the question, describing the kaldi solution.)

Note: There was another problem which came up after this problem was solved. See the bottom of this answer for help with that.

I kept working on this, and I found the answer ended up being changing the line in question (and some others) as I will show. As a reminder, the line in question was from the file, src/asclite/core/recording.h

recording.h:122:28: error: template argument 2 is invalid
         map<string, Filter::Filter*> filters;

I changed it to

map<string, ::Filter*> filters;

I also made the same change ( Filter::Filter* to ::Filter* ) in src/asclite/core/recording.cpp, lines 157 and 164, the results being:

157: map<string, ::Filter*>::iterator fi, fe;

164: ::Filter* ptr_elt = fi->second;

In looking for the answer and an explanation, I also found another page that has the solution, but no explanation.

There is a "Let me clarify" note in the explanation below that expounds on the fact that this is only a partial solution to the install.


Research and (Hopefully) Explanation

I first noticed that the declarations before and after the line in question had no namespace and double colon, whereas our line had Filter::Filter*, as can be seen below:

$ cat src/asclite/core/recording.h | head -n 130 | tail -24 map aligner;

        /**
         * contain all the available Scorer
         */
        map<string, Scorer*> scorer;

        /**
         * contain all the available Segmentors
         */
        map<string, Segmentor*> segmentors;

        /**
                 * contain all the available Filters
         */
        map<string, Filter::Filter*> filters;

                /**
                 * Database for the optimization speaker alignment
                 */
                SpeakerMatch* m_pSpeakerMatch;

                /** the logger */
        static Logger* logger;

I first tried removing both the Filter namespace and the two colons (::). I had found a few sites (1, 2, 3, ...), where it seems that there were no examples of namespaces and double colons in header files. They were only in implementation files. I removed Filter:: (from the line in question and from some other lines in recording.cpp), but that gave me

In file included from main.cpp:20:0:
recording.h:122:28: error: template argument 2 is invalid
         map<string, Filter*> filters;
                            ^
recording.h:122:28: error: template argument 4 is invalid

After studying the double-quote operator (e.g. here), and with the help of the other solution, I changed all Filter::Filter* to ::Filter.

It compiled with some warnings, but the rest of the installation process worked. Let me clarify The make config and make all parts worked. There were errors in the make test part, detailed in another question here (to be asked). However, running make install creates the executables that I need.

For information about the prepended double-colon, I got some help from another SO post. The two colons "stuck on" before the constructor let us know that it is in the global scope, i.e. outside of the recording.h/.cpp. This is necessary, because in recording.h/.cpp, there is another Filter method for the Recording object created. (Things are becoming clearer as I'm writing.)

$ cat src/asclite/core/recording.cpp | head -n 290 | tail -5
/**
 * Filter the references and hypothesis with the availables filters.
 */
void Recording::Filter(const vector<string> & _filters)
{

$ cat src/asclite/core/recording.h | head -n 75 | tail -4
        /**
         * Filter the references and hypothesis with the availables filters.
         */
        void Filter(const vector<string> & _filters);

I think that the reason we don't have a namespace (i.e. there's no Filter before the ::) is explained here on SO. In this post, code for a constructor in a .cpp (implementation) file is given with an explanation:

Mems::Mems() //you don't actually need to use the class keyword in your .cpp file; 
just the class name, the double colon, and the method name is enough to mark this 
as a class method

As I understand it, putting Filter::Filter in the code for a Recording object would suggest that Filter::Filter is a class method for a Recording object, but that doesn't make sense, because the first Filter before the colons obviously marks it as being a class method for a Filter object.

If this explanation is wrong or unclear, don't hesitate to fix it.

This solution fixed the issue in the question, but there was more to do before the checks for the install succeeded.

bballdave025
  • 1,347
  • 1
  • 15
  • 28