emcrisostomo / fswatch

A cross-platform file change monitor with multiple backends: Apple OS X File System Events, *BSD kqueue, Solaris/Illumos File Events Notification, Linux inotify, Microsoft Windows and a stat()-based backend.
https://emcrisostomo.github.io/fswatch/
GNU General Public License v3.0
5.06k stars 330 forks source link

Can't compile fswatch 1.5.0 on FreeBSD 9.3-RELEASE #91

Closed kjp949 closed 9 years ago

kjp949 commented 9 years ago

I can't compile fswatch 1.5 on FreeBSD 9.3. I have tried using clang 3.4, 3.5, 3.6 and 3.8. They all fail. I can compile fswatch 1.4.6 with no troubles.

Here is the output when I tried compiling with clang 3.6:

make  all-recursive
Making all in libfswatch
make  all-recursive
Making all in src
Making all in libfswatch
  CXX      c/libfswatch_mem.lo
  CXX      c/cevent.lo
  CXX      c/libfswatch.lo
  CXX      c/libfswatch_log.lo
  CXX      c++/libfswatch_exception.lo
  CXX      c++/event.lo
c++/event.cpp:26:54: error: no matching constructor for initialization of 'const std::map<fsw_event_flag, std::string>'
  static const std::map<fsw_event_flag, std::string> names_by_flag = {
                                                     ^               ~
/usr/include/c++/4.2/bits/stl_map.h:188:9: note: candidate constructor template not viable: requires 2 arguments, but 14 were
      provided
        map(_InputIterator __first, _InputIterator __last)
        ^
/usr/include/c++/4.2/bits/stl_map.h:204:9: note: candidate constructor template not viable: requires at most 4 arguments, but
      14 were provided
        map(_InputIterator __first, _InputIterator __last,
        ^
/usr/include/c++/4.2/bits/stl_map.h:165:7: note: candidate constructor not viable: requires at most 2 arguments, but 14 were
      provided
      map(const _Compare& __comp, const allocator_type& __a = allocator_type())
      ^
/usr/include/c++/4.2/bits/stl_map.h:175:7: note: candidate constructor not viable: requires single argument '__x', but 14
      arguments were provided
      map(const map& __x)
      ^
/usr/include/c++/4.2/bits/stl_map.h:157:7: note: candidate constructor not viable: requires 0 arguments, but 14 were provided
      map()
      ^
c++/event.cpp:45:54: error: no matching constructor for initialization of 'const std::map<std::string, fsw_event_flag>'
  static const std::map<std::string, fsw_event_flag> flag_by_names = {
                                                     ^               ~
/usr/include/c++/4.2/bits/stl_map.h:188:9: note: candidate constructor template not viable: requires 2 arguments, but 14 were
      provided
        map(_InputIterator __first, _InputIterator __last)
        ^
/usr/include/c++/4.2/bits/stl_map.h:204:9: note: candidate constructor template not viable: requires at most 4 arguments, but
      14 were provided
        map(_InputIterator __first, _InputIterator __last,
        ^
/usr/include/c++/4.2/bits/stl_map.h:165:7: note: candidate constructor not viable: requires at most 2 arguments, but 14 were
      provided
      map(const _Compare& __comp, const allocator_type& __a = allocator_type())
      ^
/usr/include/c++/4.2/bits/stl_map.h:175:7: note: candidate constructor not viable: requires single argument '__x', but 14
      arguments were provided
      map(const map& __x)
      ^
/usr/include/c++/4.2/bits/stl_map.h:157:7: note: candidate constructor not viable: requires 0 arguments, but 14 were provided
      map()
emcrisostomo commented 9 years ago

Hi @kpeterson11,

It's failing because that instance of std::map is constructed by assigning from an initializer list:

static const std::map names_by_flag = { pair_0, pair_1, ..., pair_n }

This is not legal on pre C++11 compilers and pre C++11 standard libraries. Depending on whether this is a compiler problem, library problem or both, we could:

  static std::map<fsw_event_flag, std::string> build_names_by_flag();
  static std::map<std::string, fsw_event_flag> build_flag_by_names();

  static const std::map<fsw_event_flag, std::string> names_by_flag = build_names_by_flag();
  static std::map<fsw_event_flag, std::string> build_names_by_flag()
  {
    std::map<fsw_event_flag, std::string> m;

#define FSW_MAKE_PAIR_FROM_NAME(p) m[p] = #p;
    FSW_MAKE_PAIR_FROM_NAME(NoOp)
    FSW_MAKE_PAIR_FROM_NAME(PlatformSpecific)
    FSW_MAKE_PAIR_FROM_NAME(Created)
    FSW_MAKE_PAIR_FROM_NAME(Updated)
    FSW_MAKE_PAIR_FROM_NAME(Removed)
    FSW_MAKE_PAIR_FROM_NAME(Renamed)
    FSW_MAKE_PAIR_FROM_NAME(OwnerModified)
    FSW_MAKE_PAIR_FROM_NAME(AttributeModified)
    FSW_MAKE_PAIR_FROM_NAME(MovedFrom)
    FSW_MAKE_PAIR_FROM_NAME(MovedTo)
    FSW_MAKE_PAIR_FROM_NAME(IsFile)
    FSW_MAKE_PAIR_FROM_NAME(IsDir)
    FSW_MAKE_PAIR_FROM_NAME(IsSymLink)
    FSW_MAKE_PAIR_FROM_NAME(Link)
#undef FSW_MAKE_PAIR_FROM_NAME

    return m;
  }

  static const std::map<std::string, fsw_event_flag> flag_by_names = build_flag_by_names();
  static std::map<std::string, fsw_event_flag> build_flag_by_names()
  {
    std::map<std::string, fsw_event_flag> m;
#define FSW_MAKE_PAIR_FROM_NAME(p) m[#p] = p;
    FSW_MAKE_PAIR_FROM_NAME(NoOp)
    FSW_MAKE_PAIR_FROM_NAME(PlatformSpecific)
    FSW_MAKE_PAIR_FROM_NAME(Created)
    FSW_MAKE_PAIR_FROM_NAME(Updated)
    FSW_MAKE_PAIR_FROM_NAME(Removed)
    FSW_MAKE_PAIR_FROM_NAME(Renamed)
    FSW_MAKE_PAIR_FROM_NAME(OwnerModified)
    FSW_MAKE_PAIR_FROM_NAME(AttributeModified)
    FSW_MAKE_PAIR_FROM_NAME(MovedFrom)
    FSW_MAKE_PAIR_FROM_NAME(MovedTo)
    FSW_MAKE_PAIR_FROM_NAME(IsFile)
    FSW_MAKE_PAIR_FROM_NAME(IsDir)
    FSW_MAKE_PAIR_FROM_NAME(IsSymLink)
    FSW_MAKE_PAIR_FROM_NAME(Link)
#undef FSW_MAKE_PAIR_FROM_NAME

    return m;
  }

Let me know if this works on FreeBSD 9.3. If it is, I will apply this patch to fswatch upstream.

emcrisostomo commented 9 years ago

Hi @kpeterson11,

I've released fswatch 1.5.1 and I've updated my FreeBSD port. This port successfully builds on 9.3-RELEASE and 10.1-RELEASE. You can find more instructions here.