Page 1 of 1

Compling custom module on OSX

Posted: 12 Jul 2013, 13:47
by boulay
Note, I was able to compile on my Windows machine. I don't need to use my mac but I was hoping to use it as an at-home development machine. It's not urgent. I'm only just learning C++ but maybe I can help get BCI2000 working on macs.

First, a CMake error.
Using OSX 10.7 and CMake 2.8.11.2 and the BCI2000 source code updated from SVN just now (Revision: 4522).

Code: Select all

-- Target #32: BCI2000Viewer (Tool, QTAPP)
CMake Error: Attempt to add a custom rule to output "/Users/cboulay/Documents/bci2000/build/CMakeFiles/core/Tools/BCI2000ExportQt/moc_MainWindow.cxx.rule" which already has a custom rule.
-- Target #33: BCI2000Export (Tool, QTAPP)
-- Target #34: BCI2000Launcher (Tool, QTAPP)
CMake Error: Attempt to add a custom rule to output "/Users/cboulay/Documents/bci2000/build/CMakeFiles/core/Tools/P300Classifier/moc_configdialog.cxx.rule" which already has a custom rule.
CMake Error: Attempt to add a custom rule to output "/Users/cboulay/Documents/bci2000/build/CMakeFiles/core/Tools/P300Classifier/moc_pages.cxx.rule" which already has a custom rule.
Sorry, I'm not good enough with CMake to fix this in the CMake files.
If I use cmake-gui and uncheck the BUILD_TOOLS option then I can configure and generate successfully for either XCode or Unix Makefiles.

I then followed the quick start guide http://www.bci2000.org/wiki/index.php/P ... tart_Guide .

Code: Select all

make NewBCI2000Module NewBCI2000Filter NewBCI2000FilterTool
worked as expected.

I used those tools to create ../src/custom/EEGfMRISignalProcessing and one of its filters GradArtRemoval
I then removed the intentional errors from PipeDefinition.cpp and GradArtRemoval.cpp
I then redid CMake's Build and Generate.

Then I tried to build this module and I get the following error:

Code: Select all

Chadwicks-MacBook-Air:build cboulay$ pwd
/Users/cboulay/Documents/bci2000/build
Chadwicks-MacBook-Air:build cboulay$ make EEGfMRISignalProcessing
[  0%] Building CXX object CMakeFiles/frameworks/CoreLib/CMakeFiles/BCI2000FrameworkCore.dir/Users/cboulay/Documents/bci2000/src/shared/filters/GenericFilter.cpp.o
In file included from /Users/cboulay/Documents/bci2000/src/shared/types/SignalProperties.h:33,
                 from /Users/cboulay/Documents/bci2000/src/shared/utils/MeasurementUnits.h:30,
                 from /Users/cboulay/Documents/bci2000/src/shared/accessors/ParamRef.h:36,
                 from /Users/cboulay/Documents/bci2000/src/shared/accessors/Environment.h:41,
                 from /Users/cboulay/Documents/bci2000/src/shared/filters/GenericFilter.h:34,
                 from /Users/cboulay/Documents/bci2000/src/shared/filters/GenericFilter.cpp:29:
/Users/cboulay/Documents/bci2000/src/shared/types/ValueList.h: In member function ‘int ValueList<T>::Size() const’:
/Users/cboulay/Documents/bci2000/src/shared/types/ValueList.h:37: error: there are no arguments to ‘size’ that depend on a template parameter, so a declaration of ‘size’ must be available
/Users/cboulay/Documents/bci2000/src/shared/types/ValueList.h:37: error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
/Users/cboulay/Documents/bci2000/src/shared/types/ValueList.h: In member function ‘bool ValueList<T>::Empty() const’:
/Users/cboulay/Documents/bci2000/src/shared/types/ValueList.h:38: error: there are no arguments to ‘empty’ that depend on a template parameter, so a declaration of ‘empty’ must be available
make[3]: *** [CMakeFiles/frameworks/CoreLib/CMakeFiles/BCI2000FrameworkCore.dir/Users/cboulay/Documents/bci2000/src/shared/filters/GenericFilter.cpp.o] Error 1
make[2]: *** [CMakeFiles/frameworks/CoreLib/CMakeFiles/BCI2000FrameworkCore.dir/all] Error 2
make[1]: *** [CMakeFiles/custom/EEGfMRISignalProcessing/CMakeFiles/EEGfMRISignalProcessing.dir/rule] Error 2
make: *** [EEGfMRISignalProcessing] Error 2
So I edited those lines in /src/shared/types/ValueList.h replacing size() and empty() with this->size() and this->empty(). Then I got a little further in the compile.

There was a common error that 'foo' is not a member of 'std'. This is because both Xcode and the gcc that come with OSX default to using an older version of the standard library. One option is to simply add

Code: Select all

#include <stdexcept>
to src/shared/bcistream/BCIException.h . However, this is not the only std-related error so the better option is probably to tell your compiler to use the new library.

If using Xcode, click on the BCI2000 project, then in the Build Settings scroll down to Apple LLVM compiler - Language. In that section change C++ Language Dialect to C++11 and change C++ Standard Library to libc++.
That gets me further but I'm then confronted with errors I don't understand.

Code: Select all

/Users/cboulay/Documents/bci2000/src/shared/utils/SockStream.h:262:38: No member named 'operator void *' in 'std::__1::basic_iostream<char>'
/Users/cboulay/Documents/bci2000/src/shared/utils/Lockable.h:91:7: Non-const lvalue reference to type 'std::ostream' (aka 'basic_ostream<char>') cannot bind to a temporary of type 'std::__1::basic_ostringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >'
If not using Xcode, but using Clang, first you'll have to download the Xcode command line tools from the Xcode>Preferences>Downloads window. You'll also have to add the following to BCI2000/build/CMakeLists.txt

Code: Select all

if(APPLE)
    set (CMAKE_CXX_FLAGS "-std=c++0x -stdlib=libc++ -g3 -Wall -O0")
endif()
Eventually this gives me the same error as using Xcode.

If not using Xcode and using gcc, first get the latest gcc following these instructions [link]http://www.ficksworkshop.com/blog/14-co ... gcc-on-mac[/link].
For all versions of gcc I tried, I could not set the CMAKE_CXX_FLAGS -stdlin=libc++ (the other flags worked). I think that flag is not necessary with gcc, however, I once again had to edit BCIException.h as above.
Once I did that, the compile went a little further but stopped at

Code: Select all

[ 19%] Building CXX object CMakeFiles/frameworks/CoreLib/CMakeFiles/BCI2000FrameworkCore.dir/Users/cboulay/Documents/bci2000/src/shared/utils/ThreadUtils.cpp.o
/Users/cboulay/Documents/bci2000/src/shared/utils/ThreadUtils.cpp: In function 'void ThreadUtils::Yield()':
/Users/cboulay/Documents/bci2000/src/shared/utils/ThreadUtils.cpp:132:3: error: '::pthread_yield' has not been declared
make[3]: *** [CMakeFiles/frameworks/CoreLib/CMakeFiles/BCI2000FrameworkCore.dir/Users/cboulay/Documents/bci2000/src/shared/utils/ThreadUtils.cpp.o] Error 1
make[2]: *** [CMakeFiles/frameworks/CoreLib/CMakeFiles/BCI2000FrameworkCore.dir/all] Error 2
make[1]: *** [CMakeFiles/custom/EEGfMRISignalProcessing/CMakeFiles/EEGfMRISignalProcessing.dir/rule] Error 2
make: *** [EEGfMRISignalProcessing] Error 2
I need a break.

If anyone out there has compiled modules successfully in OSX then please tell me which compiler you used and if you used any special compiler flags.

-Chad

Re: Compling custom module on OSX

Posted: 15 Jul 2013, 09:04
by mellinger
Hi,

thanks for describing your experiences, and suggesting fixes.
The basic problem we are currently having wrt cross-platform compatibility is that MSVC is still our main development platform due to the fact that most hardware APIs come with .lib files for MSVC.
Unfortunately, MSVC does not implement the C++ standard as strictly as gcc does, so it happens quite often that new code is broken on gcc until tested there.

Linking to dynamic libraries has been changed such that we do not depend on .lib files any more. This is currently in beta testing, so we will be able to switch to MinGW on Windows as our main development platform after the imminent 3.06 release. This will likely improve cross-platform compatibility in future versions of BCI2000.

Regards,
Juergen

Re: Compling custom module on OSX

Posted: 17 Sep 2013, 09:15
by hyperspasm
Hi Chad,
I've been recently working on getting BCI2000 (and my custom modules) to build on OSX, running 10.8.4.
I've been able to successfully get revision 4445 to build along with my custom ADC module (with make, not XCode). I haven't had any luck with any newer revisions.

shea

Re: Compling custom module on OSX

Posted: 17 Sep 2013, 12:39
by hyperspasm
boulay wrote:

Code: Select all

[ 19%] Building CXX object CMakeFiles/frameworks/CoreLib/CMakeFiles/BCI2000FrameworkCore.dir/Users/cboulay/Documents/bci2000/src/shared/utils/ThreadUtils.cpp.o
/Users/cboulay/Documents/bci2000/src/shared/utils/ThreadUtils.cpp: In function 'void ThreadUtils::Yield()':
/Users/cboulay/Documents/bci2000/src/shared/utils/ThreadUtils.cpp:132:3: error: '::pthread_yield' has not been declared
make[3]: *** [CMakeFiles/frameworks/CoreLib/CMakeFiles/BCI2000FrameworkCore.dir/Users/cboulay/Documents/bci2000/src/shared/utils/ThreadUtils.cpp.o] Error 1
make[2]: *** [CMakeFiles/frameworks/CoreLib/CMakeFiles/BCI2000FrameworkCore.dir/all] Error 2
make[1]: *** [CMakeFiles/custom/EEGfMRISignalProcessing/CMakeFiles/EEGfMRISignalProcessing.dir/rule] Error 2
make: *** [EEGfMRISignalProcessing] Error 2
My understanding is that sched_yield() is a drop-in replacement for pthread_yield() on OSX/BSD.

#include <sched.h>
int sched_yield(void);

Re: Compling custom module on OSX

Posted: 07 Mar 2014, 16:47
by boulay
I'm working on this again.

I made it a little further. If I ever get this working completely then I'll detail the hacks I had to do. But for now, maybe someone can help me with this problem:

Code: Select all

/Users/cboulay/Documents/bci2000/BCI2000/src/extlib/math/statistics/ObserverBase.cpp:235:11: error: 
      no viable overloaded '*='
This error is repeated 9 or 10 times for *=, -=, and +=.

In this particular example, two offending lines are in the following block:

Code: Select all

VectorPtr
ObserverBase::Variance( MemPool& ioPool ) const
{
  REQUIRE( Variance );
  VectorPtr result = PowerSum2Diag( ioPool );
  *result /= Count( ioPool );
  VectorPtr sqMean = Mean( ioPool );
  *sqMean *= *sqMean; //error
  *result -= *sqMean; //error
  for( size_t i = 0; i < result->size(); ++i )
    if( ( *result )[i] < 0 )
      ( *result )[i] = 0;
  return result;
}
result and sqmean are VectorPtr

Code: Select all

typedef ObjectPtr<Vector> VectorPtr;
I included the template definition for ObjectPtr here in case it helps:

Code: Select all

template <typename T>
class ObjectPtr
{ // A smart pointer class that is linked to a minimal object record.
  // For exception safety, object records contain the actual object instance,
  // and are kept in a linked list.
 public:
  struct Record
  {
    int usage;
    T object;
  };

  explicit ObjectPtr( Record& record = sNullRecord )
    : mpRecord( &record )
    { ++mpRecord->usage; }
  ObjectPtr( const ObjectPtr& other )
    : mpRecord( other.mpRecord )
    { ++mpRecord->usage; }
  ~ObjectPtr()
    { --mpRecord->usage; bciassert( mpRecord->usage >= 0 ); }
  ObjectPtr& operator=( const ObjectPtr& other )
    {
      --mpRecord->usage;
      mpRecord = other.mpRecord;
      ++mpRecord->usage;
      return *this;
    }
  T& operator()()
    { return mpRecord->object; }
  const T& operator()() const
    { return mpRecord->object; }
  T& operator*()
    { return mpRecord->object; }
  const T& operator*() const
    { return mpRecord->object; }
  T* operator->()
    { return &mpRecord->object; }
  const T* operator->() const
    { return &mpRecord->object; }

 private:
  static Record sNullRecord;
  Record* mpRecord;
};
By the way, since i am OSX 10.9 Mavericks, I have to use Qt 5.2 + CLANG LLVM. I get the same errors whether I use XCode or make. I tried changing the standard library (because that helped in the past) to no effect.