Fix #embed support in bbasm and use it when available.

This removes the atomic rename for bbasm outputs because it embeds
the resulting paths into the `.cc` files in embed mode. In any case
the write should be fast enough to not be a big risk for interrupted
builds.

This was tested with Clang 19 only (gcc hasn't had a release that
supports `#embed` yet).
This commit is contained in:
Catherine 2025-01-16 11:43:07 +00:00
parent dcfb7d8c33
commit bb2336ad73
10 changed files with 58 additions and 37 deletions

View File

@ -4,6 +4,7 @@ project(nextpnr CXX)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(CheckCXXCompilerHashEmbed)
if (NOT DEFINED CMAKE_SUPPRESS_DEVELOPER_WARNINGS) if (NOT DEFINED CMAKE_SUPPRESS_DEVELOPER_WARNINGS)
set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS 1 CACHE INTERNAL "No dev warnings") set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS 1 CACHE INTERNAL "No dev warnings")
@ -55,7 +56,11 @@ else()
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)
endif() endif()
if (WIN32) check_cxx_compiler_hash_embed(HAS_HASH_EMBED CXX_FLAGS_HASH_EMBED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_HASH_EMBED}")
if (HAS_HASH_EMBED)
set(BBASM_MODE "embed")
elseif (WIN32)
set(BBASM_MODE "resource") set(BBASM_MODE "resource")
elseif (EXTERNAL_CHIPDB) elseif (EXTERNAL_CHIPDB)
set(BBASM_MODE "binary") set(BBASM_MODE "binary")

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.25)
project(bba CXX) project(bba CXX)
find_package(Boost REQUIRED COMPONENTS find_package(Boost REQUIRED COMPONENTS

View File

@ -443,20 +443,20 @@ int main(int argc, char **argv)
for (auto &s : postText) for (auto &s : postText)
fprintf(fileOut, "%s\n", s.c_str()); fprintf(fileOut, "%s\n", s.c_str());
} else if (writeE) { } else if (writeE) {
for (auto &s : preText)
fprintf(fileOut, "%s\n", s.c_str());
fprintf(fileOut, "const char %s[%d] =\n", streams[0].name.c_str(), int(data.size()) + 1);
fprintf(fileOut, "#embed_str \"%s\"\n", boost::filesystem::path(files.at(2)).stem().c_str());
fprintf(fileOut, ";\n");
for (auto &s : postText)
fprintf(fileOut, "%s\n", s.c_str());
FILE *fileBin = fopen(files.at(2).c_str(), "wb"); FILE *fileBin = fopen(files.at(2).c_str(), "wb");
assert(fileBin != nullptr); assert(fileBin != nullptr);
fwrite(data.data(), int(data.size()), 1, fileBin); fwrite(data.data(), int(data.size()), 1, fileBin);
fclose(fileBin); fclose(fileBin);
for (auto &s : preText)
fprintf(fileOut, "%s\n", s.c_str());
fprintf(fileOut, "const char %s[%d] = {\n", streams[0].name.c_str(), int(data.size()) + 1);
fprintf(fileOut, "#embed \"%s\"\n", boost::filesystem::path(files.at(2)).c_str());
fprintf(fileOut, "};\n");
for (auto &s : postText)
fprintf(fileOut, "%s\n", s.c_str());
} else { } else {
fwrite(data.data(), int(data.size()), 1, fileOut); fwrite(data.data(), int(data.size()), 1, fileOut);
} }

View File

@ -81,11 +81,7 @@ function(add_bba_compile_command)
COMMAND COMMAND
bbasm ${BBASM_ENDIAN_FLAG} bbasm ${BBASM_ENDIAN_FLAG}
${arg_INPUT} ${arg_INPUT}
${arg_OUTPUT}.new ${arg_OUTPUT}
COMMAND
${CMAKE_COMMAND} -E rename # atomic update
${arg_OUTPUT}.new
${arg_OUTPUT}
DEPENDS DEPENDS
bbasm bbasm
${arg_INPUT} ${arg_INPUT}
@ -120,16 +116,8 @@ function(add_bba_compile_command)
COMMAND COMMAND
bbasm ${BBASM_ENDIAN_FLAG} --e bbasm ${BBASM_ENDIAN_FLAG} --e
${arg_INPUT} ${arg_INPUT}
${arg_OUTPUT}.cc.new ${arg_OUTPUT}.cc
${arg_OUTPUT}.new ${arg_OUTPUT}
COMMAND
${CMAKE_COMMAND} -E rename # atomic update
${arg_OUTPUT}.cc.new
${arg_OUTPUT}.cc
COMMAND
${CMAKE_COMMAND} -E rename # atomic update
${arg_OUTPUT}.new
${arg_OUTPUT}
DEPENDS DEPENDS
bbasm bbasm
${arg_INPUT} ${arg_INPUT}
@ -149,17 +137,20 @@ function(add_bba_compile_command)
COMMAND COMMAND
bbasm ${BBASM_ENDIAN_FLAG} --c bbasm ${BBASM_ENDIAN_FLAG} --c
${arg_INPUT} ${arg_INPUT}
${arg_OUTPUT}.cc.new ${arg_OUTPUT}.cc
COMMAND
${CMAKE_COMMAND} -E rename # atomic update
${arg_OUTPUT}.cc.new
${arg_OUTPUT}.cc
DEPENDS DEPENDS
bbasm bbasm
${arg_INPUT} ${arg_INPUT}
VERBATIM VERBATIM
) )
if (NOT MSVC)
set_source_files_properties(
${arg_OUTPUT}.cc PROPERTIES
COMPILE_OPTIONS "-w;-g0;-O0"
)
endif()
target_sources( target_sources(
${arg_TARGET} PRIVATE ${arg_TARGET} PRIVATE
${arg_OUTPUT}.cc ${arg_OUTPUT}.cc

View File

@ -0,0 +1,30 @@
# This is checking for CMAKE_CXX_COMPILER's ability to use `#embed`.
# BBAsm is using `#embed` (C) and not `std::embed` (C++) even though it emits C++ code.
# As of 2025-01-16: Note that the usage of `#embed` in C has different rules (the C++ one is
# an extension, the C one is in the C23 standard).
# Example usage:
#
# check_cxx_compiler_hash_embed(HAS_HASH_EMBED CXX_FLAGS_HASH_EMBED)
# set(CMAKE_CXX_FLAGS ${CXX_FLAGS_HASH_EMBED} ${CMAKE_CXX_FLAGS})
#
function(check_cxx_compiler_hash_embed VAR FLAGS_VAR)
try_compile(
${VAR}
SOURCE_FROM_CONTENT
compiletest.cc
"const char s[] = {\n#embed \"${CMAKE_CURRENT_FUNCTION_LIST_FILE}\"\n};\nint main() {}"
)
if (${VAR})
if (FLAGS_VAR)
check_cxx_compiler_flag(-Wc23-extensions HAS_Wc23-extensions)
if (HAS_Wc23-extensions)
set(${FLAGS_VAR} -Wno-c23-extensions PARENT_SCOPE)
endif()
endif()
message(STATUS "C++ compiler supports #embed")
else()
message(STATUS "C++ compiler does NOT support #embed")
endif()
endfunction()

View File

@ -1,7 +1,6 @@
include(FindTrellis) include(FindTrellis)
add_library(chipdb-${family} OBJECT) add_library(chipdb-${family} OBJECT)
target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0)
target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
target_include_directories(chipdb-${family} PRIVATE .) target_include_directories(chipdb-${family} PRIVATE .)

View File

@ -1,7 +1,6 @@
include(FindApycula) include(FindApycula)
add_library(chipdb-${family} OBJECT) add_library(chipdb-${family} OBJECT)
target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0)
target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
target_include_directories(chipdb-${family} PRIVATE .) target_include_directories(chipdb-${family} PRIVATE .)

View File

@ -1,7 +1,6 @@
include(FindIceStorm) include(FindIceStorm)
add_library(chipdb-${family} OBJECT) add_library(chipdb-${family} OBJECT)
target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0)
target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
target_include_directories(chipdb-${family} PRIVATE .) target_include_directories(chipdb-${family} PRIVATE .)

View File

@ -1,7 +1,6 @@
include(FindTrellis) include(FindTrellis)
add_library(chipdb-${family} OBJECT) add_library(chipdb-${family} OBJECT)
target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0)
target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
target_include_directories(chipdb-${family} PRIVATE .) target_include_directories(chipdb-${family} PRIVATE .)

View File

@ -7,7 +7,6 @@ set(NEXUS_FAMILIES ${ALL_NEXUS_FAMILIES} CACHE STRING
message(STATUS "Enabled Nexus families: ${NEXUS_FAMILIES}") message(STATUS "Enabled Nexus families: ${NEXUS_FAMILIES}")
add_library(chipdb-${family} OBJECT) add_library(chipdb-${family} OBJECT)
target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0)
target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
target_include_directories(chipdb-${family} PRIVATE .) target_include_directories(chipdb-${family} PRIVATE .)