Problems compiling 1.4.2 under Mac OSX

Started by stewart, May 25, 2015, 02:41:14 AM

Previous topic - Next topic
Hi,

Looks like the current version 1.4.2 is only available for download for Windows. I tried loading the ALTTP resources in the latest Mac version and it didn't work. Therefore, I'm trying to build the library and editor for Mac OSX.

I ran into a couple of issues:

While running 'cmake':

1) Missing source file in cmake build


CMake Error at cmake/AddSolarusLibrary.cmake:422 (add_library):
  Cannot find source file:

    include/lowlevel/apple/AppleInterface.h

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
  .hxx .in .txx
Call Stack (most recent call first):
  CMakeLists.txt:9 (include)


This can be fixed by:


@@ -414,7 +414,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
   set(source_files
     ${source_files}
     src/lowlevel/apple/AppleInterface.mm
-    include/lowlevel/apple/AppleInterface.h
+    include/solarus/lowlevel/apple/AppleInterface.h
   )
endif()


2) MACOS_RPATH warning:


CMake Warning (dev):
  Policy CMP0042 is not set: MACOSX_RPATH is enabled by default.  Run "cmake
  --help-policy CMP0042" for policy details.  Use the cmake_policy command to
  set the policy and suppress this warning.

  MACOSX_RPATH is not specified for the following targets:

   solarus
   solarus_testing

This warning is for project developers.  Use -Wno-dev to suppress it.


As the warning says, this can be suppressed using -Wno-dev, and cmake will complete successfully.

While running 'make':

3) Many errors regarding STL templates...


Scanning dependencies of target solarus
[  1%] Building CXX object CMakeFiles/solarus.dir/src/entities/AnimatedTilePattern.cpp.o
In file included from /Users/stewart/local/git/solarus/src/entities/AnimatedTilePattern.cpp:17:
In file included from /Users/stewart/local/git/solarus/include/solarus/entities/AnimatedTilePattern.h:21:
In file included from /Users/stewart/local/git/solarus/include/solarus/entities/TilePattern.h:22:
/Users/stewart/local/git/solarus/include/solarus/lowlevel/SurfacePtr.h:29:25: error:
      no type named 'shared_ptr' in namespace 'std'
using SurfacePtr = std::shared_ptr<Surface>;
                   ~~~~~^


This appears to be related to Apple's support for STL. For example, see here:
http://stackoverflow.com/questions/13445742/apple-and-shared-ptr
and
http://stackoverflow.com/questions/12819886/no-type-named-shared-ptr-in-namespace-std

Any ideas what to do about this? I am not very familiar with C++/STL or cmake so its a bit hard for me to debug this.

Cheers,
  Stewart

Hi,

Vlag (our Mac OS X expert) has not made the compilation of Solarus 1.4 yet.
1) This was my fault indeed, I just fixed it.
2) I have no idea what MACOS_RPATH is, vlag can probably help us.
3) This is very weird. Solarus is now compiled as C++11 so shared_ptr is part of STL.

As far as I can tell, C++11 is not supported by the standard g++ compiler on Mac OSX.  :(

It looks like you have to:
1) use clang++ rather than g++
2) link against libc++

http://stackoverflow.com/questions/14228856/how-to-compile-c-with-c11-support-in-mac-terminal
http://blog.michael.kuron-germany.de/2013/02/using-c11-on-mac-os-x-10-8/

OK, I messed around a bit with the CMAKE settings (diffs below) and got a little further.

One issue: The use of C++11 via libc++ restricts you to Mac OSX version at least 10.7.

Another issue: it looks like thread-local storage may be disabled for the C++11 library.

http://stackoverflow.com/questions/23791060/c-thread-local-storage-clang-503-0-40-mac-osx


Building CXX object CMakeFiles/solarus.dir/src/lowlevel/Random.cpp.o
/Users/stewart/local/git/solarus/src/lowlevel/Random.cpp:74:3: error:
      thread-local storage is unsupported for the current target
  thread_local std::mt19937 engine(std::time(nullptr));
  ^


Diffs so far:

diff --git a/cmake/AddCompilationFlags.cmake b/cmake/AddCompilationFlags.cmake
index 2002c8f..a405e93 100644
--- a/cmake/AddCompilationFlags.cmake
+++ b/cmake/AddCompilationFlags.cmake
@@ -4,6 +4,10 @@
if(MINGW)
   # To avoid a compilation error in vorbisfile.h with fseeko64.
   set(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}")
+elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+  SET (CMAKE_CXX_COMPILER "/usr/bin/clang++")
+#  SET (CMAKE_OSX_DEPLOYMENT_TARGET "10.7")
+  SET (CMAKE_CXX_FLAGS "-std=c++11  -stdlib=libc++ -Wall ${CMAKE_CXX_FLAGS}")
else()
   set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
endif()
diff --git a/cmake/AddSolarusLibrary.cmake b/cmake/AddSolarusLibrary.cmake
index d5a7286..4c61419 100644
--- a/cmake/AddSolarusLibrary.cmake
+++ b/cmake/AddSolarusLibrary.cmake
@@ -414,7 +414,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
   set(source_files
     ${source_files}
     src/lowlevel/apple/AppleInterface.mm
-    include/lowlevel/apple/AppleInterface.h
+    include/solarus/lowlevel/apple/AppleInterface.h
   )
endif()

diff --git a/cmake/modules/OSX.cmake b/cmake/modules/OSX.cmake
index 5660041..8f96327 100755
--- a/cmake/modules/OSX.cmake
+++ b/cmake/modules/OSX.cmake
@@ -54,8 +54,8 @@ set(CMAKE_OSX_SYSROOT "${SOLARUS_SYSROOT}" CACHE STRING "Build

# Deployment version
if(NOT SOLARUS_DEPLOYMENT AND DEFINED SOLARUS_SYSROOT)
-  if(NOT ${SOLARUS_CURRENT_OSX_VERSION_LONG} VERSION_LESS "10.6")
-    set(SOLARUS_DEPLOYMENT "10.6")
+  if(NOT ${SOLARUS_CURRENT_OSX_VERSION_LONG} VERSION_LESS "10.7")
+    set(SOLARUS_DEPLOYMENT "10.7")
   else()
     set(SOLARUS_DEPLOYMENT "10.2")
   endif()
diff --git a/src/lowlevel/QuestFiles.cpp b/src/lowlevel/QuestFiles.cpp
index 6252085..01dfef2 100644
--- a/src/lowlevel/QuestFiles.cpp
+++ b/src/lowlevel/QuestFiles.cpp
@@ -29,7 +29,7 @@
#endif

#if defined(SOLARUS_OSX) || defined(SOLARUS_IOS)
-#   include "lowlevel/apple/AppleInterface.h"
+#   include "solarus/lowlevel/apple/AppleInterface.h"
#endif

namespace Solarus {


Hi again.

Just letting you know that I got it working. ;D

I was able to build the git version of the Solarus engine (1.5.0) and it seems to run fine on my Macbook running OSX 10.8.5. This involved a couple of hacks which may not be legitimate:

1) Removed the thread_local declaration in Random.cpp. Will this do bad things?
2) There is problem with copy constructors in due to the "const" declaration on value_type in FieldValue (see error below). I removed the "const" declaration.
3) I had to force x86_64 build, since the libraries I used were built for this architecture. You could possibly do a 32-bit build, but this is no longer the default on Mac OSX.
4) I built zsdx from the git repository, but had to change the solaris version in quest.dat to 1.5, since this is what the engine (also built from git) seems to expect.


[  0%] Building CXX object CMakeFiles/solarus.dir/src/EntityData.cpp.o
In file included from /Users/stewart/local/git/solarus/src/EntityData.cpp:17:
In file included from /Users/stewart/local/git/solarus/include/solarus/EntityData.h:24:
In file included from /Users/stewart/local/git/solarus/include/solarus/lua/LuaData.h:22:
In file included from /usr/bin/../lib/c++/v1/string:434:
In file included from /usr/bin/../lib/c++/v1/algorithm:593:
/usr/bin/../lib/c++/v1/utility:256:16: error: object of type
      'Solarus::EntityData::FieldValue' cannot be assigned because its copy
      assignment operator is implicitly deleted
        second = __p.second;
               ^
/usr/bin/../lib/c++/v1/__tree:1246:35: note: in instantiation of member function
      'std::__1::pair<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue>::operator=' requested here
                __cache->__value_ = *__first;
                                  ^
/usr/bin/../lib/c++/v1/__tree:1187:9: note: in instantiation of function
      template specialization
      'std::__1::__tree<std::__1::pair<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue>,
      std::__1::__map_value_compare<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue,
      std::__1::less<std::__1::basic_string<char> >, true>,
      std::__1::allocator<std::__1::pair<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue> >
      >::__assign_multi<std::__1::__tree_const_iterator<std::__1::pair<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue>, const
      std::__1::__tree_node<std::__1::pair<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue>, void *> *, int> >' requested here
        __assign_multi(__t.begin(), __t.end());
        ^
/usr/bin/../lib/c++/v1/map:766:21: note: in instantiation of member function
      'std::__1::__tree<std::__1::pair<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue>,
      std::__1::__map_value_compare<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue,
      std::__1::less<std::__1::basic_string<char> >, true>,
      std::__1::allocator<std::__1::pair<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue> > >::operator=' requested here
            __tree_ = __m.__tree_;
                    ^
/Users/stewart/local/git/solarus/include/solarus/EntityData.h:38:19: note: in
      instantiation of member function
      'std::__1::map<std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue,
      std::__1::less<std::__1::basic_string<char> >,
      std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>,
      Solarus::EntityData::FieldValue> > >::operator=' requested here
class SOLARUS_API EntityData : public LuaData {
                  ^
/Users/stewart/local/git/solarus/include/solarus/EntityData.h:66:31: note: copy
      assignment operator of 'FieldValue' is implicitly deleted because field
      'value_type' is of const-qualified type 'const
      Solarus::EntityData::EntityFieldType'
        const EntityFieldType value_type;


Here are the complete changes required to get it working.


diff --git a/cmake/AddCompilationFlags.cmake b/cmake/AddCompilationFlags.cmake
index 2002c8f..a405e93 100644
--- a/cmake/AddCompilationFlags.cmake
+++ b/cmake/AddCompilationFlags.cmake
@@ -4,6 +4,10 @@
if(MINGW)
   # To avoid a compilation error in vorbisfile.h with fseeko64.
   set(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}")
+elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+  SET (CMAKE_CXX_COMPILER "/usr/bin/clang++")
+#  SET (CMAKE_OSX_DEPLOYMENT_TARGET "10.7")
+  SET (CMAKE_CXX_FLAGS "-std=c++11  -stdlib=libc++ -Wall ${CMAKE_CXX_FLAGS}")
else()
   set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
endif()
diff --git a/cmake/AddSolarusLibrary.cmake b/cmake/AddSolarusLibrary.cmake
index d5a7286..4c61419 100644
--- a/cmake/AddSolarusLibrary.cmake
+++ b/cmake/AddSolarusLibrary.cmake
@@ -414,7 +414,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
   set(source_files
     ${source_files}
     src/lowlevel/apple/AppleInterface.mm
-    include/lowlevel/apple/AppleInterface.h
+    include/solarus/lowlevel/apple/AppleInterface.h
   )
endif()

diff --git a/cmake/modules/OSX.cmake b/cmake/modules/OSX.cmake
index 5660041..a8fb99f 100755
--- a/cmake/modules/OSX.cmake
+++ b/cmake/modules/OSX.cmake
@@ -20,19 +20,23 @@ string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)\\[ \t\r
string(REGEX REPLACE "([0-9]+)\\.([0-9]+).*" "\\1.\\2" SOLARUS_CURRENT_OSX_VERS

# Build architectures
+#if(NOT SOLARUS_ARCH)
+#  if(NOT ${SOLARUS_CURRENT_OSX_VERSION_LONG} VERSION_LESS "10.4.4")
+#    set(SOLARUS_ARCH "${SOLARUS_ARCH}i386;")
+#  endif()
+#  if(NOT ${SOLARUS_CURRENT_OSX_VERSION_LONG} VERSION_LESS "10.5")
+#    # WORKAROUND : LuaJIT needs additional linker flag with the 64bit build.
+#    # CMake can't set arch-specific flag with Makefile and Ninja generators fo
+#    # so make a 32bit-only build if LuaJit and i386 are requested without XCod
+#    if(XCODE OR NOT SOLARUS_USE_LUAJIT OR NOT SOLARUS_ARCH MATCHES "i386")
+#      set(SOLARUS_ARCH "${SOLARUS_ARCH}x86_64;")
+#    endif()
+#  endif()
+#endif()
if(NOT SOLARUS_ARCH)
-  if(NOT ${SOLARUS_CURRENT_OSX_VERSION_LONG} VERSION_LESS "10.4.4")
-    set(SOLARUS_ARCH "${SOLARUS_ARCH}i386;")
-  endif()
-  if(NOT ${SOLARUS_CURRENT_OSX_VERSION_LONG} VERSION_LESS "10.5")
-    # WORKAROUND : LuaJIT needs additional linker flag with the 64bit build.
-    # CMake can't set arch-specific flag with Makefile and Ninja generators for
-    # so make a 32bit-only build if LuaJit and i386 are requested without XCode
-    if(XCODE OR NOT SOLARUS_USE_LUAJIT OR NOT SOLARUS_ARCH MATCHES "i386")
-      set(SOLARUS_ARCH "${SOLARUS_ARCH}x86_64;")
-    endif()
-  endif()
+  set(SOLARUS_ARCH "${SOLARUS_ARCH}x86_64;")
endif()
+
set(CMAKE_OSX_ARCHITECTURES "${SOLARUS_ARCH}" CACHE STRING "Build architecture"

# SDK version
@@ -54,8 +58,8 @@ set(CMAKE_OSX_SYSROOT "${SOLARUS_SYSROOT}" CACHE STRING "Build

# Deployment version
if(NOT SOLARUS_DEPLOYMENT AND DEFINED SOLARUS_SYSROOT)
-  if(NOT ${SOLARUS_CURRENT_OSX_VERSION_LONG} VERSION_LESS "10.6")
-    set(SOLARUS_DEPLOYMENT "10.6")
+  if(NOT ${SOLARUS_CURRENT_OSX_VERSION_LONG} VERSION_LESS "10.7")
+    set(SOLARUS_DEPLOYMENT "10.7")
   else()
     set(SOLARUS_DEPLOYMENT "10.2")
   endif()
diff --git a/include/solarus/EntityData.h b/include/solarus/EntityData.h
index 9c2e1bf..1b06225 100644
--- a/include/solarus/EntityData.h
+++ b/include/solarus/EntityData.h
@@ -63,7 +63,8 @@ class SOLARUS_API EntityData : public LuaData {
         bool operator==(const FieldValue& other) const;
         bool operator!=(const FieldValue& other) const;

-        const EntityFieldType value_type;
+//        const EntityFieldType value_type;
+        EntityFieldType value_type;
         std::string string_value;
         int int_value;  // Also used for boolean.
     };
diff --git a/src/lowlevel/QuestFiles.cpp b/src/lowlevel/QuestFiles.cpp
index 6252085..01dfef2 100644
--- a/src/lowlevel/QuestFiles.cpp
+++ b/src/lowlevel/QuestFiles.cpp
@@ -29,7 +29,7 @@
#endif

#if defined(SOLARUS_OSX) || defined(SOLARUS_IOS)
-#   include "lowlevel/apple/AppleInterface.h"
+#   include "solarus/lowlevel/apple/AppleInterface.h"
#endif

namespace Solarus {
diff --git a/src/lowlevel/Random.cpp b/src/lowlevel/Random.cpp
index 770e154..590e2fb 100644
--- a/src/lowlevel/Random.cpp
+++ b/src/lowlevel/Random.cpp
@@ -18,6 +18,8 @@
#include <ctime>
#include <random>

+#define thread_local
+
namespace Solarus {
namespace Random {

diff --git a/src/lowlevel/apple/AppleInterface.mm b/src/lowlevel/apple/AppleInte
index b572068..48f15c0 100755
--- a/src/lowlevel/apple/AppleInterface.mm
+++ b/src/lowlevel/apple/AppleInterface.mm
@@ -14,7 +14,7 @@
  * You should have received a copy of the GNU General Public License along
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
-#include "lowlevel/apple/AppleInterface.h"
+#include "solarus/lowlevel/apple/AppleInterface.h"

#if defined(SOLARUS_OSX) || defined(SOLARUS_IOS)


Nice! I think your changes are okay, vlag will have to confirm that.