Skip to content

cmake: Auto discover NXDK_DIR #742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/pkgconfig/nxdk_automount_d.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Name: nxdk_automount_d
Description: Automatic mounting of the "D:" for nxdk XBEs.
Version: 1.0.0
Requires:
Conflicts:
Libs: -l${NXDK_DIR}/lib/libnxdk_automount_d.lib
Cflags:
7 changes: 7 additions & 0 deletions lib/pkgconfig/nxdk_net.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Name: nxdk_net
Description: Network functionality for the NXDK
Version: 1.0.0
Requires:
Conflicts:
Libs: -l${NXDK_DIR}/lib/libnxdk_net.lib
Cflags: -I${NXDK_DIR}/lib/net/lwip/src/include -I${NXDK_DIR}/lib/net/nforceif/include -I${NXDK_DIR}/lib/net/nvnetdrv
7 changes: 7 additions & 0 deletions lib/pkgconfig/pbkit.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Name: pbkit
Description: Pushbuffer management
Version: 1.0.0
Requires:
Conflicts:
Libs: -l${NXDK_DIR}/lib/libpbkit.lib
Cflags:
7 changes: 7 additions & 0 deletions lib/pkgconfig/winmm.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Name: winmm
Description: WinAPI multimedia extensions
Version: 1.0.0
Requires:
Conflicts:
Libs: -l${NXDK_DIR}/lib/winmm.lib
Cflags:
14 changes: 8 additions & 6 deletions share/toolchain-nxdk.cmake
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
if(DEFINED ENV{NXDK_DIR})
set(NXDK_DIR $ENV{NXDK_DIR})
else()
message(FATAL_ERROR "The environment variable NXDK_DIR needs to be defined.")
endif()
get_filename_component(NXDK_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
set(NXDK_DIR "${NXDK_ROOT_DIR}" CACHE PATH "Path to the nxdk root directory.")
message(STATUS "Using NXDK from: ${NXDK_DIR}")

set(ENV{NXDK_DIR} "${NXDK_DIR}")

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
Expand All @@ -18,6 +18,8 @@ set(WIN32 1)

set(NXDK 1)

set(CMAKE_ASM_COMPILER "${NXDK_DIR}/bin/${TOOLCHAIN_PREFIX}-as")

set(CMAKE_C_COMPILER "${NXDK_DIR}/bin/${TOOLCHAIN_PREFIX}-cc")
set(CMAKE_C_COMPILER_AR "llvm-ar")
set(CMAKE_C_COMPILER_RANLIB "llvm-ranlib")
Expand Down Expand Up @@ -66,7 +68,7 @@ set(_CMAKE_C_IPO_SUPPORTED_BY_CMAKE YES)
set(_CMAKE_C_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
set(CMAKE_C_COMPILE_OPTIONS_IPO -flto)

set(PKG_CONFIG_EXECUTABLE "${NXDK_DIR}/bin/nxdk-pkg-config" CACHE STRING "Path to pkg-config")
set(PKG_CONFIG_EXECUTABLE "${NXDK_DIR}/bin/${TOOLCHAIN_PREFIX}-pkg-config" CACHE STRING "Path to pkg-config")

# Fix generation of ninja depfiles
set(CMAKE_DEPFILE_FLAGS_C "-MD -MF <OBJECT>.d")
Expand Down
42 changes: 42 additions & 0 deletions tests/cmake/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash

set -eu
set -o pipefail

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
readonly SCRIPT_DIR

NXDK_ROOT_DIR="$( realpath ${SCRIPT_DIR}/../.. )"
BIN_DIR="${NXDK_ROOT_DIR}/bin"
readonly BIN_DIR
SHARE_DIR="${NXDK_ROOT_DIR}/share"
readonly SHARE_DIR

echo "Verify that building works without the NXDK_DIR environment variable set."
TOOLCHAIN_FILE="${SHARE_DIR}/toolchain-nxdk.cmake"
unset NXDK_DIR
pushd test_project &> /dev/null
rm -rf build-noenvvar &> /dev/null
cmake -DCMAKE_TOOLCHAIN_FILE="${TOOLCHAIN_FILE}" -S . -B build-noenvvar
cmake --build build-noenvvar
rm -rf build-noenvvar &> /dev/null
popd &> /dev/null
echo "Build without env-var completed!"


NXDK_CMAKE="${BIN_DIR}/nxdk-cmake"
readonly NXDK_CMAKE

echo "Verify that building works with the NXDK_DIR environment variable set."
pushd "${BIN_DIR}" &> /dev/null
. activate -s
popd &> /dev/null

pushd test_project &> /dev/null
rm -rf build-envvar &> /dev/null
"${NXDK_CMAKE}" -S . -B build-envvar
cmake --build build-envvar
rm -rf build-envvar &> /dev/null
popd &> /dev/null

echo "Build with env-var completed!"
68 changes: 68 additions & 0 deletions tests/cmake/test_project/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
cmake_minimum_required(VERSION 3.30)

project(nxdk_cmake_test_project LANGUAGES CXX C ASM)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(_CMAKE_PROCESSING_LANGUAGE "CXX")
set(CMAKE_VERBOSE_MAKEFILE ON)

if (NOT CMAKE_TOOLCHAIN_FILE MATCHES "toolchain-nxdk.cmake")
message(FATAL_ERROR "This project must be built with the nxdk toolchain (`-DCMAKE_TOOLCHAIN_FILE=<YOUR_NXDK_DIR>/share/toolchain-nxdk.cmake`)")
endif ()

include(FindPkgConfig)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules")
include(XBEUtils REQUIRED)

pkg_check_modules(
nxdk_packages
REQUIRED
SDL2_image
SDL2_ttf
libjpeg
libpng
nxdk_automount_d
nxdk_net
pbkit
sdl2
winmm
zlib
)

add_executable(
${PROJECT_NAME}
src/main.cpp
src/c_file.c
src/asm_file.s
)

target_include_directories(
${PROJECT_NAME}
PRIVATE
${nxdk_packages_INCLUDE_DIRS}
)

target_link_libraries(
${PROJECT_NAME}
PRIVATE
${nxdk_packages_LIBRARIES}
)

target_compile_options(
${PROJECT_NAME}
PRIVATE
${nxdk_packages_CFLAGS}
)

# TODO: Determine if there is an alternative to allow handwritten assembly.
target_link_options(${PROJECT_NAME} PRIVATE "/SAFESEH:NO")


set(EXECUTABLE_BINARY "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.exe")
add_xbe(
xbe_file "${EXECUTABLE_BINARY}"
TITLE "Useless test xbe"
)
add_xiso(${PROJECT_NAME}_xiso xbe_file)
156 changes: 156 additions & 0 deletions tests/cmake/test_project/cmake/modules/XBEUtils.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Provides:
#
# add_xbe(
# target executable_file
# [XBENAME <xbe_filename>="default.xbe"]
# [TITLE <xbe title>={target}]
# )
#
# Generates an XBE file from the given executable_file.
#
# add_xiso(target xbe_target [XISO <filename>=<target>.xiso])
# Generates an xiso image for the given XBE.

include(CMakeParseArguments)

set(CXBE_TOOL_PATH "${NXDK_DIR}/tools/cxbe/cxbe")
set(EXTRACT_XISO_TOOL_PATH "${NXDK_DIR}/tools/extract-xiso/build/extract-xiso")

# Makes each path in the given list into an absolute path.
function(_make_abs_paths list_name)
set(ret "")
foreach (src "${${list_name}}")
get_filename_component(abs "${src}" ABSOLUTE)
list(APPEND ret "${abs}")
endforeach ()
set(${list_name} ${ret} PARENT_SCOPE)
endfunction()

# split_debug(executable_target)
#
# Splits debugging information from the given `executable_target`, generating a companion file ending in ".debug.exe".
function(split_debug)
if (${ARGC} LESS 1)
message(FATAL_ERROR "Missing required 'executable_target' parameter.")
endif ()

set(executable_target "${ARGV0}")
set(exe_file "${CMAKE_CURRENT_BINARY_DIR}/${executable_target}.exe")
get_filename_component(exe_dirname "${CMAKE_CURRENT_BINARY_DIR}/${executable_target}" DIRECTORY)
get_filename_component(exe_basename "${executable_target}" NAME_WE)
set(output "${exe_dirname}/${exe_basename}.debug.exe")

add_custom_command(
TARGET "${executable_target}"
POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy "${exe_file}" "${output}"
COMMAND "${CMAKE_OBJCOPY}" --strip-debug "${exe_file}"
COMMAND "${CMAKE_OBJCOPY}" "--add-gnu-debuglink=${output}" "${exe_file}"
COMMENT "Splitting debug information to reduce binary size..."
VERBATIM
BYPRODUCTS "${output}"
)
endfunction()

# Adds an XBE file.
function(add_xbe)
cmake_parse_arguments(
PARSE_ARGV
2
"XBE"
""
"XBENAME;TITLE"
""
)

if (${ARGC} LESS 1)
message(FATAL_ERROR "Missing required 'target' parameter.")
elseif (${ARGC} LESS 2)
message(FATAL_ERROR "Missing required 'executable_file' parameter.")
endif ()

set(target "${ARGV0}")
set(exe_file "${ARGV1}")

if (NOT XBE_XBENAME)
set(XBE_XBENAME default.xbe)
endif ()

if (NOT XBE_TITLE)
set(XBE_TITLE "${target}")
endif ()

set(
"${target}_XBE_STAGING_DIR"
"${CMAKE_CURRENT_BINARY_DIR}/xbe/${target}"
CACHE INTERNAL
"Directory into which the raw sources for an xiso have been placed."
)
set(XBE_STAGING_DIR "${${target}_XBE_STAGING_DIR}")

set(
"${target}_XBE_OUTPUT_PATH"
"${${target}_XBE_STAGING_DIR}/${XBE_XBENAME}"
CACHE INTERNAL
"XBE file that should be added to an xiso."
)
set(XBE_OUTPUT_PATH "${${target}_XBE_OUTPUT_PATH}")

add_custom_command(
OUTPUT "${XBE_STAGING_DIR}"
COMMAND "${CMAKE_COMMAND}" -E make_directory "${XBE_STAGING_DIR}"
)

file(MAKE_DIRECTORY "${XBE_STAGING_DIR}")

add_custom_command(
OUTPUT "${XBE_OUTPUT_PATH}"
COMMAND "${CXBE_TOOL_PATH}"
"-TITLE:${XBE_TITLE}"
"-OUT:${XBE_OUTPUT_PATH}"
"${exe_file}"
DEPENDS "${exe_file}"
)
endfunction()

function(add_xiso)
cmake_parse_arguments(
PARSE_ARGV
2
"XISO"
""
"XISO"
""
)

if (${ARGC} LESS 1)
message(FATAL_ERROR "Missing required 'target' parameter.")
elseif (${ARGC} LESS 2)
message(FATAL_ERROR "Missing required 'xbe_target' parameter.")
endif ()
set(target "${ARGV0}")
set(xbe_target "${ARGV1}")

if (NOT XISO_XISO)
set(XISO_XISO "${target}.iso")
endif ()

set(XBE_STAGING_DIR "${${xbe_target}_XBE_STAGING_DIR}")
set(XBE_OUTPUT_PATH "${${xbe_target}_XBE_OUTPUT_PATH}")
set(XISO_STAGING_DIR "${CMAKE_CURRENT_BINARY_DIR}/xiso/${target}")
file(MAKE_DIRECTORY "${XISO_STAGING_DIR}")
set(XISO_OUTPUT_PATH "${XISO_STAGING_DIR}/${XISO_XISO}")

add_custom_command(
OUTPUT "${XISO_OUTPUT_PATH}"
COMMAND "${EXTRACT_XISO_TOOL_PATH}" -c "${XBE_STAGING_DIR}" "${XISO_OUTPUT_PATH}"
DEPENDS
"${XBE_OUTPUT_PATH}"
)

add_custom_target(
"${target}"
ALL
DEPENDS
"${XISO_OUTPUT_PATH}")
endfunction()
14 changes: 14 additions & 0 deletions tests/cmake/test_project/src/asm_file.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.globl _add_ten

# Define the start of the text/code section
.text

_add_ten:
pushl %ebp
movl %esp, %ebp

movl 8(%ebp), %eax
addl $10, %eax

leave
ret
5 changes: 5 additions & 0 deletions tests/cmake/test_project/src/c_file.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <hal/video.h>

BOOL verify_c_file_builds() {
return XVideoSetMode(640, 480, 32, REFRESH_DEFAULT);
}
14 changes: 14 additions & 0 deletions tests/cmake/test_project/src/c_file.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef NXDK_TESTS_CMAKE_TEST_PROJECT_C_FILE_H_
#define NXDK_TESTS_CMAKE_TEST_PROJECT_C_FILE_H_

#ifdef __cplusplus
extern "C" {
#endif

BOOL verify_c_file_builds();

#ifdef __cplusplus
} // extern "C"
#endif

#endif // NXDK_TESTS_CMAKE_TEST_PROJECT_C_FILE_H_
Loading
Loading