80 lines
3.1 KiB
CMake
80 lines
3.1 KiB
CMake
|
|
||
|
# =============================================================================
|
||
|
# 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()
|
||
|
|