rpsdk-mix-c-rs-zig/cmake/zig-obj.cmake

80 lines
3.1 KiB
CMake
Raw Normal View History

2025-01-09 22:57:00 +00:00
# =============================================================================
# first, get some info about the compiler
# get zig binary
if(NOT DEFINED ZIG_BIN OR ZIG_BIN STREQUAL "")
find_program(ZIG_BIN zig REQUIRED)
endif()
set(ZIG_BIN ${ZIG_BIN} CACHE FILEPATH "Zig command")
message(NOTICE "-- ZIG_BIN is ${ZIG_BIN}")
# get zig libdir (for zig.h)
execute_process(
COMMAND ${ZIG_BIN} env
OUTPUT_VARIABLE ZIG_LIBDIR
)
string(JSON ZIG_LIBDIR GET ${ZIG_LIBDIR} lib_dir)
set(ZIG_LIBDIR ${ZIG_LIBDIR} CACHE PATH "from `zig env`")
# =============================================================================
# set compile options
if(DEFINED ZIG_TARGET)
list(APPEND ZIG_CFLAGS "-target" "${ZIG_TARGET}")
endif()
if(DEFINED ZIG_CPU)
list(APPEND ZIG_CFLAGS "-mcpu=${ZIG_CPU}")
endif()
if(NOT DEFINED ZIG_OPTLEVEL)
if(CMAKE_BUILD_TYPE STREQUAL Release)
set(ZIG_OPTLEVEL ReleaseFast)
elseif(CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
set(ZIG_OPTLEVEL ReleaseSafe)
elseif(CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
set(ZIG_OPTLEVEL ReleaseSmall)
else()
# also the Debug case
set(ZIG_OPTLEVEL ${CMAKE_BUILD_TYPE})
endif()
endif()
list(APPEND ZIG_CFLAGS "-O" "${ZIG_OPTLEVEL}")
# =============================================================================
# now define the macro we'll be using
function(add_zig_object TOP_PROJECT ZIG_TOP_SOURCE_FILE)
if(ARGC GREATER 2)
set(TARGET_NAME ${ARGV2})
else()
cmake_path(GET ZIG_TOP_SOURCE_FILE STEM TARGET_NAME)
endif()
# directory the header file will be in
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated/zig_${TARGET_NAME}/)
# the compile command
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.obj
# TODO: when is this generator expression evaluated??? (matters for direct rust<->zig references)
COMMAND ${ZIG_BIN} build-obj ${ZIG_CFLAGS} -femit-bin=${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.obj -femit-h=${CMAKE_CURRENT_BINARY_DIR}/generated/zig_${TARGET_NAME}/${TARGET_NAME}.h "$<LIST:TRANSFORM,$<TARGET_PROPERTY:${TOP_PROJECT},INCLUDE_DIRECTORIES>,PREPEND,-I>" ${ZIG_TOP_SOURCE_FILE}
# ${TARGET_NAME}.obj.o is a bug in zig currently
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.obj.o ${CMAKE_CURRENT_BINARY_DIR}/generated/zig_${TARGET_NAME}/${TARGET_NAME}.h
MAIN_DEPENDENCY ${ZIG_TOP_SOURCE_FILE}
DEPENDS ${ZIG_TOP_SOURCE_FILE}
#DEPFILE ${TARGET_NAME}.obj.d # no way to generate it :/
VERBATIM
COMMAND_EXPAND_LISTS
)
# add a virtual library that can be reused and referred to (not possible with a bare add_custom_command())
add_library(${TARGET_NAME} OBJECT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.obj)
# add generated object file from the library to the code to compile
target_sources(${TOP_PROJECT} PUBLIC $<TARGET_PROPERTY:${TARGET_NAME},SOURCES>)
# add directory of zig.h and the generated header to the top project's stuff
target_include_directories(${TOP_PROJECT} PRIVATE ${ZIG_LIBDIR} ${CMAKE_CURRENT_BINARY_DIR}/generated/zig_${TARGET_NAME}/)
# work around https://github.com/ziglang/zig/issues/16730
target_compile_definitions(${TOP_PROJECT} PUBLIC ZIG_TARGET_MAX_INT_ALIGNMENT="\(sizeof\(intmax_t\)\)")
endfunction()