Skip to content

Commit

Permalink
[switch] Build with CMake (#334)
Browse files Browse the repository at this point in the history
* Switch port: Code changes for latest devkitpro
* switch/build.sh: Fewer devkitpro packages
  • Loading branch information
glebm authored and AJenbo committed Nov 11, 2019
1 parent 274cd35 commit 235b8e2
Show file tree
Hide file tree
Showing 10 changed files with 503 additions and 106 deletions.
10 changes: 8 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,14 @@ jobs:
working_directory: ~/repo
steps:
- checkout
- run: make -j$(nproc)
- store_artifacts: {path: ./release/devilutionx.nro, destination: devilutionx.nro}
- run: echo deb http://deb.debian.org/debian stretch-backports main > /etc/apt/sources.list.d/debian-backports.list
- run: apt-get update && apt-get install -y -t stretch-backports cmake
# Install cmake files (https://github.com/devkitPro/docker/issues/3)
- run: dkp-pacman -S --needed --noconfirm --quiet devkitpro-pkgbuild-helpers
# NOTE: Doesn't link without LTO ("read-only segment has dynamic relocations").
- run: cd build && cmake .. -DBINARY_RELEASE=ON -DNONET=ON -DCMAKE_TOOLCHAIN_FILE=../CMake/switch/devkita64-libnx.cmake
- run: cd build && cmake --build . -j $(nproc)
- store_artifacts: {path: ./build/devilutionx.nro, destination: devilutionx.nro}

workflows:
version: 2
Expand Down
3 changes: 2 additions & 1 deletion 3rdParty/StormLib/src/StormPort.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <assert.h>
#include <errno.h>
Expand Down Expand Up @@ -276,7 +277,7 @@
#endif // !PLATFORM_WINDOWS

// 64-bit calls are supplied by "normal" calls on Mac
#if defined(PLATFORM_MAC) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) || defined(PLATFORM_NX)
#if defined(PLATFORM_MAC) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) || defined(PLATFORM_SWITCH)
#define stat64 stat
#define fstat64 fstat
#define lseek64 lseek
Expand Down
44 changes: 44 additions & 0 deletions CMake/switch/FindLIBNX.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# https://github.com/switchpy/libnx-template/blob/7037982c77e1767410143103d5963d0ddc77fb64/cmake/FindLIBNX.cmake

# Tries to find libnx
# Once done, this will define:
# > LIBNX_FOUND - The system has libnx
# > LIBNX_INCLUDE_DIRS - The libnx include directories
# > LIBNX_LIBRARIES - The libnx libraries required for using it
#
# It also adds an imported target named `switch::libnx`.

include(utils) # <- devilutionX patch

if (NOT SWITCH)
cmake_panic("This helper can only be used if you are using the Switch toolchain file.")
endif ()

set(LIBNX_PATHS $ENV{LIBNX} libnx ${LIBNX} ${DEVKITPRO}/libnx)

find_path(LIBNX_INCLUDE_DIR switch.h
PATHS ${LIBNX_PATHS}
PATH_SUFFIXES include)

find_library(LIBNX_LIBRARY NAMES libnx.a
PATHS ${LIBNX_PATHS}
PATH_SUFFIXES lib)

set(LIBNX_INCLUDE_DIRS ${LIBNX_INCLUDE_DIR})
set(LIBNX_LIBRARIES ${LIBNX_LIBRARY})

# Handle the QUIETLY and REQUIRED arguments and set LIBNX_FOUND to TRUE if all above variables are TRUE.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LIBNX DEFAULT_MSG
LIBNX_INCLUDE_DIR LIBNX_LIBRARY)

mark_as_advanced(LIBNX_INCLUDE_DIR LIBNX_LIBRARY)
if (LIBNX_FOUND)
set(LIBNX ${LIBNX_INCLUDE_DIR}/..)
cmake_info("Setting LIBNX to ${LIBNX}")

add_library(switch::libnx STATIC IMPORTED GLOBAL)
set_target_properties(switch::libnx PROPERTIES
IMPORTED_LOCATION ${LIBNX_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${LIBNX_INCLUDE_DIR})
endif ()
46 changes: 46 additions & 0 deletions CMake/switch/devkita64-libnx.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
if(NOT DEFINED ENV{DEVKITPRO})
message(FATAL_ERROR "Please set the DEVKITPRO env var to <path to devkitpro>")
endif()

# devkitPro paths are broken on Windows. We need to use this macro to fix those.
# from https://github.com/switchpy/libnx-template/blob/7037982c77e1767410143103d5963d0ddc77fb64/devkita64-libnx.cmake
macro(msys_to_cmake_path msys_path resulting_path)
if (WIN32)
string(REGEX REPLACE "^/([a-zA-Z])/" "\\1:/" ${resulting_path} ${msys_path})
else ()
set(${resulting_path} ${msys_path})
endif ()
endmacro()
msys_to_cmake_path($ENV{DEVKITPRO} DEVKITPRO)

# Default devkitpro cmake
include(${DEVKITPRO}/switch.cmake)

# Set root paths:
set(DEVKITA64 ${DEVKITPRO}/devkitA64)
set(LIBNX ${DEVKITPRO}/libnx)
set(PORTLIBS_PATH ${DEVKITPRO}/portlibs)
set(PORTLIBS ${PORTLIBS_PATH}/switch)
set(CMAKE_FIND_ROOT_PATH ${DEVKITA64} ${LIBNX} ${PORTLIBS})

# Set absolute tool paths:
set(TOOLCHAIN_PREFIX ${DEVKITA64}/bin/aarch64-none-elf-)
if(WIN32)
set(TOOLCHAIN_SUFFIX ".exe")
else()
set(TOOLCHAIN_SUFFIX "")
endif()
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc${TOOLCHAIN_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++${TOOLCHAIN_SUFFIX})
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}as${TOOLCHAIN_SUFFIX})
set(PKG_CONFIG_EXECUTABLE ${TOOLCHAIN_PREFIX}pkg-config${TOOLCHAIN_SUFFIX})
set(CMAKE_AR ${TOOLCHAIN_PREFIX}gcc-ar${TOOLCHAIN_SUFFIX} CACHE STRING "")
set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}gcc-ranlib${TOOLCHAIN_SUFFIX} CACHE STRING "")
set(CMAKE_LD "/${TOOLCHAIN_PREFIX}ld${TOOLCHAIN_SUFFIX}" CACHE INTERNAL "")
set(CMAKE_OBJCOPY "${TOOLCHAIN_PREFIX}objcopy${TOOLCHAIN_SUFFIX}" CACHE INTERNAL "")
set(CMAKE_SIZE_UTIL "${TOOLCHAIN_PREFIX}size${TOOLCHAIN_SUFFIX}" CACHE INTERNAL "")

set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Shared libs not available")

set(SWITCH ON) # To be used for multiplatform projects
add_definitions(-D__SWITCH__ -DSWITCH -D_POSIX_C_SOURCE=200809L)
186 changes: 186 additions & 0 deletions CMake/switch/nx-utils.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# https://github.com/vbe0201/libnx-template/blob/5283aabad32789675542ef98dad9c91838a3e729/cmake/nx-utils.cmake

if (NOT SWITCH)
cmake_panic("These utils can only be used if you are using the Switch toolchain file.")
endif ()

#############
## ELF2NRO ##
#############
if (NOT ELF2NRO)
find_program(ELF2NRO elf2nro ${DEVKITPRO}/tools/bin)
if (ELF2NRO)
cmake_info("elf2nro: ${ELF2NRO} - found")
else ()
cmake_warning("elf2nro - not found")
endif ()
endif ()

#############
## ELF2KIP ##
#############
if (NOT ELF2KIP)
find_program(ELF2KIP elf2kip ${DEVKITPRO}/tools/bin)
if (ELF2KIP)
cmake_info("elf2kip: ${ELF2KIP} - found")
else ()
cmake_warning("elf2kip - not found")
endif ()
endif ()

#############
## ELF2NSO ##
#############
if (NOT ELF2NSO)
find_program(ELF2NSO elf2nso ${DEVKITPRO}/tools/bin)
if (ELF2NSO)
cmake_info("elf2nso: ${ELF2NSO} - found")
else ()
cmake_warning("elf2nso - not found")
endif ()
endif ()

#############
## BIN2S ##
#############
if (NOT BIN2S)
find_program(BIN2S bin2s ${DEVKITPRO}/tools/bin)
if (BIN2S)
cmake_info("bin2s: ${BIN2S} - found")
else ()
cmake_warning("bin2s - not found")
endif ()
endif ()

#############
## RAW2C ##
#############
if (NOT RAW2C)
find_program(RAW2C raw2c ${DEVKITPRO}/tools/bin)
if (RAW2C)
cmake_info("raw2c: ${RAW2C} - found")
else ()
cmake_warning("raw2c - not found")
endif ()
endif ()

##################
## BUILD_PFS0 ##
##################
if (NOT BUILD_PFS0)
find_program(BUILD_PFS0 build_pfs0 ${DEVKITPRO}/tools/bin)
if (BUILD_PFS0)
cmake_info("build_pfs0: ${BUILD_PFS0} - found")
else ()
cmake_warning("build_pfs0 - not found")
endif ()
endif ()

################
## NACPTOOL ##
################
if (NOT NACPTOOL)
find_program(NACPTOOL nacptool ${DEVKITPRO}/tools/bin)
if (NACPTOOL)
cmake_info("nacptool: ${NACPTOOL} - found")
else ()
cmake_warning("nacptool - not found")
endif ()
endif ()

macro(acquire_homebrew_icon target)
# This basically imitates the behavior of the Makefiles
# from the switchbrew/switch-examples repository.
if (EXISTS ${target}.jpg)
set(APP_ICON ${target}.jpg)
elseif (EXISTS ${PROJECT_SOURCE_DIR}/assets/icon.jpg)
set(APP_ICON ${PROJECT_SOURCE_DIR}/assets/icon.jpg)
elseif (LIBNX)
set(APP_ICON ${LIBNX}/default_icon.jpg)
else ()
cmake_panic("No icon found, please provide one!")
endif ()
endmacro()

function(add_nso_target target)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.nso
COMMAND ${ELF2NSO} ${CMAKE_CURRENT_BINARY_DIR}/${target}.elf ${CMAKE_CURRENT_BINARY_DIR}/${target}.nso
DEPENDS ${target}.elf
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
VERBATIM)

if (CMAKE_RUNTIME_OUTPUT_DIRECTORY)
add_custom_target(${target}.nso ALL SOURCES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}.nso)
else ()
add_custom_target(${target}.nso ALL SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${target}.nso)
endif ()
endfunction()

function(add_nacp target)
set(__NACP_COMMAND ${NACPTOOL} --create ${APP_TITLE} ${APP_AUTHOR} ${APP_VERSION} ${CMAKE_CURRENT_BINARY_DIR}/${target})

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}
COMMAND ${__NACP_COMMAND}
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
VERBATIM)
endfunction()

function(add_nro_target target)
set(__NRO_COMMAND
${ELF2NRO} $<TARGET_FILE:${target}.elf> ${CMAKE_CURRENT_BINARY_DIR}/${target}.nro --nacp=${CMAKE_CURRENT_BINARY_DIR}/${target}.nacp --icon=${APP_ICON})

if (NOT ${CMAKE_CURRENT_BINARY_DIR}/${target}.nacp)
add_nacp(${target}.nacp)
endif ()

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.nro
COMMAND ${__NRO_COMMAND}
DEPENDS ${target}.elf ${CMAKE_CURRENT_BINARY_DIR}/${target}.nacp
VERBATIM)

if (CMAKE_RUNTIME_OUTPUT_DIRECTORY)
add_custom_target(${target}.nro ALL SOURCES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}.nro)
else ()
add_custom_target(${target}.nro ALL SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${target}.nro)
endif ()
endfunction()

function(build_switch_binaries target)
get_filename_component(target_we ${target} NAME_WE)

if (NOT APP_TITLE)
if (${ARGC} GREATER 1)
set(APP_TITLE ${ARGV1})
else ()
set(APP_TITLE ${target_we})
endif ()
endif ()

if (NOT APP_AUTHOR)
if (${ARGC} GREATER 2)
set(APP_AUTHOR ${ARGV2})
else ()
set(APP_AUTHOR "Unspecified Author")
endif ()
endif ()

if (NOT APP_ICON)
if (${ARGC} GREATER 4)
set(APP_ICON ${ARGV4})
else ()
acquire_homebrew_icon(${target_we})
endif ()
endif ()

if (NOT APP_VERSION)
if (${ARGC} GREATER 3)
set(APP_VERSION ${ARGV3})
else ()
set(APP_VERSION "1.0.0")
endif ()
endif ()

# Build the binaries
add_nso_target(${target_we})
add_nro_target(${target_we})
endfunction()
17 changes: 17 additions & 0 deletions CMake/switch/utils.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# https://github.com/switchpy/libnx-template/blob/7037982c77e1767410143103d5963d0ddc77fb64/cmake/utils.cmake

function(cmake_info message)
if (cmake_VERBOSE)
message("Build-Info: ${message}")
endif ()
endfunction()

function(cmake_warning message)
if (cmake_VERBOSE)
message(WARNING "${message}")
endif ()
endfunction()

function(cmake_panic message)
message(FATAL_ERROR "${message}")
endfunction()
Loading

0 comments on commit 235b8e2

Please sign in to comment.