
The impetus for this commit is the fact that it causes rare but build-breaking race conditions when used with `make -jN` with `N > 1`. These race conditions are difficult to track down or fix because of the very rudmentary debugging tools provided by `make` and opaque semantics of CMake's Makefile generator. They break the build by running two `.bba` generation processes, then one of them renaming the `.bba.new` file once it's done, leaving the other one to fail. After reflection (as the author of this code path) and discussion with community members who use it, I've concluded that this isn't the right approach. 1. In practice, on targets where `-DSERIALIZE_CHIPDBS=` matters, you also care about other build steps, like linking nextpnr, which are not serializable this way. So you use a workaround anyway, like `make`ing individual targets instead. 2. The way to serialize the build with Make is the `-j1` option. Trying to work around `-jN` to make it work like `-j1` is inherently error prone. While there is some utility in not serializing C++ compilation this utility could be more easily achieved by providing a single target that builds all chipdbs, running `make <chipdb-target> -j1`, then running `make -jN` for the rest of the build.
172 lines
4.6 KiB
CMake
172 lines
4.6 KiB
CMake
include(TestBigEndian)
|
|
|
|
test_big_endian(IS_BIG_ENDIAN)
|
|
if (IS_BIG_ENDIAN)
|
|
set(BBASM_ENDIAN_FLAG "--be")
|
|
else()
|
|
set(BBASM_ENDIAN_FLAG "--le")
|
|
endif()
|
|
|
|
# Example usage (note the `.new`, used for atomic updates):
|
|
#
|
|
# add_bba_produce_command(
|
|
# COMMAND ${Python_EXECUTABLE}
|
|
# ${CMAKE_CURRENT_SOURCE_DIR}/chipdb.py
|
|
# -o ${CMAKE_CURRENT_BINARY_DIR}/chipdb-hx8k.bba.new
|
|
# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/chipdb-hx8k.bba
|
|
# INPUTS ${CMAKE_CURRENT_SOURCE_DIR}/chipdb.py
|
|
# )
|
|
#
|
|
# Paths must be absolute.
|
|
#
|
|
function(add_bba_produce_command)
|
|
cmake_parse_arguments(arg "" "OUTPUT" "COMMAND;INPUTS" ${ARGN})
|
|
|
|
cmake_path(GET arg_OUTPUT PARENT_PATH arg_OUTPUT_DIR)
|
|
file(MAKE_DIRECTORY ${arg_OUTPUT_DIR})
|
|
|
|
list(GET arg_COMMAND 0 arg_EXECUTABLE)
|
|
|
|
add_custom_command(
|
|
OUTPUT
|
|
${arg_OUTPUT}
|
|
COMMAND
|
|
${arg_COMMAND}
|
|
COMMAND
|
|
${CMAKE_COMMAND} -E rename # atomic update
|
|
${arg_OUTPUT}.new
|
|
${arg_OUTPUT}
|
|
DEPENDS
|
|
${arg_EXECUTABLE}
|
|
${arg_INPUTS}
|
|
VERBATIM
|
|
)
|
|
|
|
endfunction()
|
|
|
|
# Example usage:
|
|
#
|
|
# add_bba_compile_command(
|
|
# TARGET chipdb-ice40
|
|
# OUTPUT ice40/chipdb-1k.bin
|
|
# INPUT ${CMAKE_CURRENT_BINARY_DIR}/chipdb-1k.bba
|
|
# MODE binary
|
|
# )
|
|
#
|
|
# Paths must be absolute.
|
|
#
|
|
function(add_bba_compile_command)
|
|
cmake_parse_arguments(arg "" "TARGET;OUTPUT;INPUT;MODE" "" ${ARGN})
|
|
|
|
cmake_path(GET arg_OUTPUT PARENT_PATH arg_OUTPUT_DIR)
|
|
cmake_path(GET arg_OUTPUT FILENAME arg_OUTPUT_NAME)
|
|
|
|
set(arg_PRODUCT ${CMAKE_BINARY_DIR}/share/${arg_OUTPUT})
|
|
cmake_path(GET arg_PRODUCT PARENT_PATH arg_PRODUCT_DIR)
|
|
|
|
if (arg_MODE STREQUAL "binary" OR arg_MODE STREQUAL "resource")
|
|
|
|
add_custom_command(
|
|
OUTPUT
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}
|
|
COMMAND
|
|
bbasm ${BBASM_ENDIAN_FLAG}
|
|
${arg_INPUT}
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}
|
|
DEPENDS
|
|
bbasm
|
|
${arg_INPUT}
|
|
VERBATIM
|
|
)
|
|
|
|
if (arg_MODE STREQUAL "resource")
|
|
|
|
file(WRITE ${arg_OUTPUT}.rc
|
|
"${arg_OUTPUT} RCDATA \"${arg_OUTPUT}\"")
|
|
|
|
target_sources(
|
|
${arg_TARGET} PUBLIC
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}.rc
|
|
)
|
|
|
|
else()
|
|
|
|
target_sources(
|
|
${arg_TARGET} PUBLIC
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}
|
|
)
|
|
|
|
add_custom_command(
|
|
OUTPUT
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}
|
|
COMMAND
|
|
${CMAKE_COMMAND} -E make_directory
|
|
${arg_PRODUCT_DIR}
|
|
COMMAND
|
|
${CMAKE_COMMAND} -E copy
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}
|
|
${arg_PRODUCT}
|
|
APPEND
|
|
VERBATIM
|
|
)
|
|
|
|
install(
|
|
FILES ${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}
|
|
DESTINATION share/nextpnr/${arg_OUTPUT_DIR}
|
|
)
|
|
|
|
endif()
|
|
|
|
elseif (arg_MODE STREQUAL "embed")
|
|
|
|
add_custom_command(
|
|
OUTPUT
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}.cc
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}
|
|
COMMAND
|
|
bbasm ${BBASM_ENDIAN_FLAG} --e
|
|
${arg_INPUT}
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}.cc
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}
|
|
DEPENDS
|
|
bbasm
|
|
${arg_INPUT}
|
|
VERBATIM
|
|
)
|
|
|
|
target_sources(
|
|
${arg_TARGET} PUBLIC
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}.cc
|
|
)
|
|
|
|
elseif (arg_MODE STREQUAL "string")
|
|
|
|
add_custom_command(
|
|
OUTPUT
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}.cc
|
|
COMMAND
|
|
bbasm ${BBASM_ENDIAN_FLAG} --c
|
|
${arg_INPUT}
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}.cc
|
|
DEPENDS
|
|
bbasm
|
|
${arg_INPUT}
|
|
VERBATIM
|
|
)
|
|
|
|
if (NOT MSVC)
|
|
set_source_files_properties(
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}.cc PROPERTIES
|
|
COMPILE_OPTIONS "-w;-g0;-O0"
|
|
)
|
|
endif()
|
|
|
|
target_sources(
|
|
${arg_TARGET} PUBLIC
|
|
${CMAKE_CURRENT_BINARY_DIR}/${arg_OUTPUT_NAME}.cc
|
|
)
|
|
|
|
endif()
|
|
|
|
endfunction()
|