diff --git a/.gitignore b/.gitignore index 7f07a2a68..9cd04a357 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,8 @@ src/wx/cmdtab.cpp src/wx/wxvbam.xrs build/ +# vim swap files +*.sw? + +# mac finder crap +*.DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt index 11a3a1222..62d889457 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,13 +65,6 @@ ELSE() ADD_DEFINITIONS(-DNDEBUG) ENDIF() -# Fill in SDLMAIN_LIBRARY on OS X manually to avoid using SDLMain.m -# OS X users will have to compile and install SDL from source. -if( APPLE AND ENABLE_SDL ) - ADD_DEFINITIONS (-DwxMAC_USE_CORE_GRAPHICS ) - SET(SDL2MAIN_LIBRARY "-lSDL2main") -endif( APPLE AND ENABLE_SDL ) - # Add support for Homebrew, MacPorts and Fink on OS X # as well as for ObjectiveC code IF(APPLE) @@ -107,7 +100,7 @@ IF(APPLE) # and compile as Objective-C++ for ObjectiveC #ifdefs SET(CMAKE_CXX_COMPILE_OBJECT " -x objective-c++ -o -c ") -ENDIF() +ENDIF(APPLE) # We do not support amd64 asm yet IF((ENABLE_ASM_CORE OR ENABLE_ASM_SCALERS OR ENABLE_MMX) @@ -129,17 +122,26 @@ if( ENABLE_ASM_SCALERS ) endif( ENABLE_ASM_SCALERS ) # Look for some dependencies using CMake scripts -FIND_PACKAGE ( ZLIB REQUIRED ) -FIND_PACKAGE ( PNG REQUIRED ) -FIND_PACKAGE ( OpenGL REQUIRED ) -FIND_PACKAGE ( SDL2 REQUIRED ) +FIND_PACKAGE(ZLIB REQUIRED) +FIND_PACKAGE(OpenGL REQUIRED) + +# TODO: make static on mac +FIND_PACKAGE(PNG REQUIRED) + +IF(APPLE) + SET(SDL2_STATIC ON) +ENDIF(APPLE) + +FIND_PACKAGE(SDL2 REQUIRED) +ADD_DEFINITIONS(${SDL2_DEFINITIONS}) if( ENABLE_LINK ) - if( WIN32 ) + if(WIN32 OR APPLE) set(SFML_STATIC_LIBRARIES TRUE) - endif( WIN32 ) + endif(WIN32 OR APPLE) FIND_PACKAGE ( SFML 2 COMPONENTS network system ) endif( ENABLE_LINK ) + # set the standard libraries all ports use SET(VBAMCORE_LIBS vbamcore diff --git a/CMakeScripts/FindSDL2.cmake b/CMakeScripts/FindSDL2.cmake index 026dc34e7..78f823963 100644 --- a/CMakeScripts/FindSDL2.cmake +++ b/CMakeScripts/FindSDL2.cmake @@ -1,9 +1,22 @@ - # This module defines # SDL2_LIBRARY, the name of the library to link against # SDL2_FOUND, if false, do not try to link to SDL2 # SDL2_INCLUDE_DIR, where to find SDL.h # +# If you have pkg-config, these extra variables are also defined: +# SDL2_DEFINITIONS, extra CFLAGS +# SDL2_EXTRA_LIBS, extra link libs +# SDL2_LINKER_FLAGS, extra link flags +# +# The latter two are automatically added to SDL2_LIBRARY +# +# To use them, add code such as: +# +# # SET(SDL2_STATIC ON) # if you want to link SDL2 statically +# FIND_PACKAGE(SDL2 REQUIRED) +# ADD_DEFINITIONS(${SDL2_DEFINITIONS}) +# TARGET_LINK_LIBRARIES(your-executable-target ${SDL2_LIBRARY} ...) +# # This module responds to the the flag: # SDL2_BUILDING_LIBRARY # If this is defined, then no SDL2main will be linked in because @@ -12,6 +25,8 @@ # module will attempt to locate and set the the proper link flags # as part of the returned SDL2_LIBRARY variable. # +# If you want to link SDL2 statically, set SDL2_STATIC to ON. +# # Don't forget to include SDLmain.h and SDLmain.m your project for the # OS X framework based version. (Other versions link to -lSDL2main which # this module will try to find on your behalf.) Also for OS X, this @@ -47,7 +62,7 @@ # SDL2_LIBRARY to override this selection or set the CMake environment # CMAKE_INCLUDE_PATH to modify the search paths. # -# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# Note that the header path has changed from SDL3/SDL.h to just SDL.h # This needed to change because "proper" SDL convention # is #include "SDL.h", not . This is done for portability # reasons because not all systems place things in SDL2/ (see FreeBSD). @@ -86,11 +101,21 @@ FIND_PATH(SDL2_INCLUDE_DIR SDL.h PATHS ${SDL2_SEARCH_PATHS} ) +SET(CURRENT_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + +IF(SDL2_STATIC) + IF(WIN32) + SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a) + ELSE(WIN32) + SET(CMAKE_FIND_LIBRARY_SUFFIXES .a) + ENDIF(WIN32) +ENDIF(SDL2_STATIC) + FIND_LIBRARY(SDL2_LIBRARY_TEMP NAMES SDL2 HINTS $ENV{SDL2DIR} - PATH_SUFFIXES lib64 lib + PATH_SUFFIXES lib64 lib lib/x64 lib/x86 PATHS ${SDL2_SEARCH_PATHS} ) @@ -104,12 +129,15 @@ IF(NOT SDL2_BUILDING_LIBRARY) NAMES SDL2main HINTS $ENV{SDL2DIR} - PATH_SUFFIXES lib64 lib + PATH_SUFFIXES lib64 lib lib/x64 lib/x86 PATHS ${SDL2_SEARCH_PATHS} ) ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") ENDIF(NOT SDL2_BUILDING_LIBRARY) +SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CURRENT_FIND_LIBRARY_SUFFIXES}) +UNSET(CURRENT_FIND_LIBRARY_SUFFIXES) + # SDL2 may require threads on your system. # The Apple build may not need an explicit flag because one of the # frameworks may already provide it. @@ -118,11 +146,10 @@ IF(NOT APPLE) FIND_PACKAGE(Threads) ENDIF(NOT APPLE) -# MinGW needs an additional library, mwindows -# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows -# (Actually on second look, I think it only needs one of the m* libraries.) +# MinGW needs an additional link flag, -mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows IF(MINGW) - SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") + SET(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "mwindows for MinGW") ENDIF(MINGW) IF(SDL2_LIBRARY_TEMP) @@ -155,6 +182,37 @@ IF(SDL2_LIBRARY_TEMP) SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) ENDIF(MINGW) + # Add some stuff from pkg-config, if available + IF(NOT PKG_CONFIG_EXECUTABLE) + FIND_PACKAGE(PkgConfig QUIET) + ENDIF(NOT PKG_CONFIG_EXECUTABLE) + + IF(PKG_CONFIG_EXECUTABLE) + # get any definitions + EXECUTE_PROCESS(COMMAND ${PKG_CONFIG_EXECUTABLE} --cflags-only-other sdl2 OUTPUT_VARIABLE SDL2_DEFINITIONS) + + SET(SDL2_DEFINITIONS ${SDL2_DEFINITIONS} CACHE STRING "Extra CFLAGS for SDL2 from pkg-config") + + # get any extra stuff needed for linking + IF(NOT SDL2_STATIC) + EXECUTE_PROCESS(COMMAND ${PKG_CONFIG_EXECUTABLE} --libs-only-other sdl2 OUTPUT_VARIABLE SDL2_LINKER_FLAGS_RAW OUTPUT_STRIP_TRAILING_WHITESPACE) + + EXECUTE_PROCESS(COMMAND ${PKG_CONFIG_EXECUTABLE} --libs-only-l sdl2 OUTPUT_VARIABLE SDL2_EXTRA_LIBS_RAW OUTPUT_STRIP_TRAILING_WHITESPACE) + ELSE(NOT SDL2_STATIC) + EXECUTE_PROCESS(COMMAND ${PKG_CONFIG_EXECUTABLE} --static --libs-only-other sdl2 OUTPUT_VARIABLE SDL2_LINKER_FLAGS_RAW OUTPUT_STRIP_TRAILING_WHITESPACE) + EXECUTE_PROCESS(COMMAND ${PKG_CONFIG_EXECUTABLE} --static --libs-only-l sdl2 OUTPUT_VARIABLE SDL2_EXTRA_LIBS_RAW OUTPUT_STRIP_TRAILING_WHITESPACE) + ENDIF(NOT SDL2_STATIC) + + STRING(REGEX REPLACE "[^ ]+SDL2[^ ]*" "" SDL2_EXTRA_LIBS_RAW2 "${SDL2_EXTRA_LIBS_RAW}") + STRING(REGEX REPLACE " +" ";" SDL2_EXTRA_LIBS "${SDL2_EXTRA_LIBS_RAW2}") + STRING(REGEX REPLACE " +" ";" SDL2_LINKER_FLAGS "${SDL2_LINKER_FLAGS_RAW}") + + SET(SDL2_LINKER_FLAGS ${SDL2_LINKER_FLAGS} CACHE STRING "Linker flags for linking SDL2") + SET(SDL2_EXTRA_LIBS ${SDL2_EXTRA_LIBS} CACHE STRING "Extra libraries for linking SDL2") + + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${SDL2_EXTRA_LIBS} ${SDL2_LINKER_FLAGS}) + ENDIF(PKG_CONFIG_EXECUTABLE) + # Set the final string here so the GUI reflects the final state. SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") # Set the temp variable to INTERNAL so it is not seen in the CMake GUI @@ -166,4 +224,3 @@ message("") INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) - diff --git a/src/wx/CMakeLists.txt b/src/wx/CMakeLists.txt index d492fe7f6..9821028a5 100644 --- a/src/wx/CMakeLists.txt +++ b/src/wx/CMakeLists.txt @@ -1,8 +1,17 @@ #Do not use this file directly. Always use the top level CMakeLists.txt file # This build is much easier if we just do it here. SET( CMAKE_CXX_FLAGS -std=gnu++11 ) + # not yet implemented -option( ENABLE_CAIRO "Enable Cairo rendering for the wxWidgets port" ON ) +IF(APPLE) + # does not work, no reason to link to it + SET(CAIRO_DEFAULT OFF) +ELSE(APPLE) + SET(CAIRO_DEFAULT ON) +ENDIF(APPLE) + +option(ENABLE_CAIRO "Enable Cairo rendering for the wxWidgets port" ${CAIRO_DEFAULT}) + if( WIN32 ) # not yet implemented option( ENABLE_DIRECT3D "Enable Direct3D rendering for the wxWidgets port" ON ) @@ -10,6 +19,10 @@ if( WIN32 ) endif( WIN32 ) option( ENABLE_OPENAL "Enable OpenAL for the wxWidgets port" ON ) +IF(APPLE) + ADD_DEFINITIONS(-DwxMAC_USE_CORE_GRAPHICS) +ENDIF(APPLE) + if( NOT ENABLE_CAIRO ) ADD_DEFINITIONS (-DNO_CAIRO) endif( NOT ENABLE_CAIRO ) @@ -38,6 +51,10 @@ IF(CMAKE_BUILD_TYPE STREQUAL "Debug") ENDIF() ENDIF() +IF(APPLE) + SET(wxWidgets_USE_STATIC ON) +ENDIF(APPLE) + SET(wxWidgets_USE_UNICODE ON) # adv is for wxAboutBox # xml, html is for xrc @@ -189,7 +206,14 @@ ENDIF( WIN32 ) link_directories( ${CMAKE_BINARY_DIR} ) -SET(VBAM_ICON ${CMAKE_CURRENT_SOURCE_DIR}/icons/vbam.icns) +SET(VBAM_ICON vbam.icns) + +SET(VBAM_ICON_PATH ${CMAKE_CURRENT_SOURCE_DIR}/icons/${VBAM_ICON}) + +IF(APPLE) + SET(CMAKE_BUILD_WITH_INSTALL_RPATH ON) + SET(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks") +ENDIF(APPLE) ADD_EXECUTABLE ( visualboyadvance-m @@ -198,7 +222,7 @@ ADD_EXECUTABLE ( ${SRC_WX} ${HDR_WX} ${RES_WX} - ${VBAM_ICON} + ${VBAM_ICON_PATH} ${CM_STUFF} ) @@ -221,7 +245,10 @@ if(APPLE) # this should set ROM file types correctly SET_PROPERTY(TARGET visualboyadvance-m APPEND PROPERTY MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/wxplist.in) SET(MACOSX_BUNDLE_ICON_FILE ${VBAM_ICON}) - SET_SOURCE_FILES_PROPERTIES(${VBAM_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + SET_SOURCE_FILES_PROPERTIES(${VBAM_ICON_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + ADD_CUSTOM_COMMAND(TARGET visualboyadvance-m POST_BUILD + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/osx/third_party_libs_tool "$/../..") endif(APPLE) SET(WX_EXE_NAME visualboyadvance-m-wx${CMAKE_EXECUTABLE_SUFFIX}) diff --git a/src/wx/tools/osx/third_party_libs_tool b/src/wx/tools/osx/third_party_libs_tool new file mode 100755 index 000000000..c3f8c85d4 --- /dev/null +++ b/src/wx/tools/osx/third_party_libs_tool @@ -0,0 +1,262 @@ +#!/bin/sh + +version=0.1 + +main() { + # parse options + list= + while [ $# -gt 0 ]; do + case "$1" in + -h|--help|--usage) + usage + quit 0 + ;; + -v|--version) + echo "third_party_libs_tool $version" + quit 0 + ;; + -l|--list) + list=1 + shift + ;; + *) + break + ;; + esac + done + + if [ $# -ne 1 ]; then + usage + quit 1 + fi + + mktmp + + app_bundle=$(echo "$1" | fully_resolve_links | sed 's,/*$,,') + + case "$app_bundle" in + *.app|*.APP) + if [ ! -d "$app_bundle" ]; then + usage + quit 1 + fi + ;; + *) + usage + quit 1 + ;; + esac + + set -- + + OLDIFS=$IFS + IFS=' +' + for file in $(find "$app_bundle/Contents/MacOS" -type f); do + case "$file" in + *.dylib) + set -- "$@" "$file" + ;; + *) + [ -x "$file" ] && set -- "$@" "$file" + ;; + esac + done + IFS=$OLDIFS + + frameworks="$app_bundle/Contents/Frameworks" + + mkdir -p "$frameworks" 2>/dev/null + + lib_scan "$@" | fully_resolve_links | sort -u | \ + while read lib; do + if [ -n "$list" ]; then + echo "$lib" + else + cp -f "$lib" "$frameworks" 2>/dev/null + fi + done + + # fix dynamic link info in executables and just copied libs + [ -z "$list" ] && relink_all "$@" + + quit 0 +} + +usage() { + cat <<'EOF' +Usage: third_party_libs_tool [OPTION] BUNDLE.app +Bundle third party dylibs into BUNDLE.app and fix up linkages. + +Binaries are searched for in BUNDLE.app/Contents/MacOS . + +The dylibs are copied into BUNDLE.app/Contents/Frameworks . + + -h, --help, --usage Show this help screen and exit. + -v, --version Show version information and exit. + -l, --list Only list dylibs used by binaries, do not copy or link. + +Examples: + third_party_libs_tool ./MyApp.app # bundle and link ./MyApp.app + third_party_libs_tool --list ./MyApp.app # list third party libs used by ./MyApp.app + +Project homepage and documentation: <http://github.com/rkitover/mac-third-party-libs-tool> +EOF +} + +mktmp() { + tmp="/tmp/third_party_libs_tool_$$" + mkdir "$tmp" || quit 1 + chmod 700 "$tmp" 2>/dev/null + trap "quit 1" PIPE HUP INT QUIT ILL TRAP KILL BUS TERM +} + +quit() { + [ -n "$tmp" ] && rm -rf "$tmp" 2>/dev/null + exit ${1:-0} +} + +lib_scan() { + for bin in "$@"; do + case "$bin" in + *.dylib) + ;; + *) + [ ! -x "$bin" ] && continue + ;; + esac + + set -- + + OLDIFS=$IFS + IFS=' +' + for lib in $(otool -L "$bin" 2>/dev/null | sed -n 's/^ \([^ ]*\).*/\1/p' | grep -v '^/System/' | grep -v '^/usr/lib/'); do + [ "$lib" = "$bin" ] && continue + + echo "$lib" + set -- "$@" "$lib" + done + IFS=$OLDIFS + + # recurse + [ $# -ne 0 ] && lib_scan "$@" + done +} + +fully_resolve_links() { + while read -r file; do + OLDIFS=$IFS + IFS=' +' + path= + for part in $(echo "$file" | sed 's,^/*,,; s,/*$,,; s,//*,\ +,g'); do + path=$(resolve_link "$path/$part") + done + IFS=$OLDIFS + + # remove '..' path parts + while :; do + case "$path" in + */../*|*/..) + path=$(echo "$path" | sed 's,//*[^/][^/]*//*\.\./*,/,g') + ;; + *) + break + ;; + esac + done + + echo "$path" + done +} + +resolve_link() { + file="$1" + + while [ -h "$file" ]; do + ls0=`ls -l "$file"` + new_link=`expr "$ls0" : '.* -> \(.*\)$'` + if expr "$new_link" : '/.*' > /dev/null; then + file="$new_link" + else + file="${file%/*}"/"$new_link" + fi + done + + echo "$file" +} + +relink_all() { + for exe in "$@"; do + # dylib search path for executable + install_name_tool -add_rpath '@loader_path/../Frameworks' "$exe" + + OLDIFS=$IFS + IFS=' +' + set -- + for lib in $(find "$app_bundle/Contents/Frameworks" -name '*.dylib'); do + set -- "$@" "$lib" + done + IFS=$OLDIFS + + for lib in "$@"; do + # make lib writable + chmod u+w "$lib" + + # change id of lib + install_name_tool -id "@rpath/${lib##*/}" "$lib" + + # set search path of lib + install_name_tool -add_rpath '@loader_path/../Frameworks' "$lib" + + # relink executable and all other libs to this lib + for target in "$exe" "$@"; do + relink "$lib" "$target" + done + done + done +} + +relink() { + lib=$1 + target=$2 + + lib_basename=${lib##*/} + lib_basename_unversioned_re=$(echo "$lib_basename" | sed 's/[0-9.-]*\.dylib$//; s/\./\\./g') + + # remove full path and version of lib in executable + lib_link_path=$( + otool -l "$target" 2>/dev/null | \ + sed -n 's,^ *name \(/.*/*'"$lib_basename_unversioned_re"'[0-9.-]*\.dylib\) (offset .*,\1,p' | \ + head -1 + ) + + if [ -n "$lib_link_path" ]; then + install_name_tool -change "$lib_link_path" "@rpath/$lib_basename" "$target" + fi +} + +# try with sudo in case it fails, +# also suppress duplicate path errors +install_name_tool() { + out_file="$tmp/install_name_tool.out" + + if ! command install_name_tool "$@" >"$out_file" 2>&1; then + if grep -Eq -i 'permission denied|bad file descriptor' "$out_file"; then + if ! command sudo install_name_tool "$@" >"$out_file" 2>&1; then + cat "$out_file" >&2 + return 1 + fi + elif ! grep -Eq -i 'would duplicate path' "$out_file"; then + cat "$out_file" >&2 + return 1 + fi + fi + + return 0 +} + +main "$@"