341 lines
12 KiB
CMake
341 lines
12 KiB
CMake
|
|
cmake_minimum_required(VERSION 3.16)
|
|
|
|
project(glcc)
|
|
enable_language(C)
|
|
|
|
|
|
# --- Default to RelWithDebInfo
|
|
|
|
if (NOT "${CMAKE_BUILD_TYPE}")
|
|
SET(CMAKE_BUILD_TYPE "RelWithDebInfo")
|
|
endif()
|
|
|
|
|
|
# --- Only support out-of-directory builds
|
|
|
|
if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
|
|
message(FATAL_ERROR "\
|
|
Compilation in the source directory is not supported.\
|
|
Please create a 'build' directory and run 'cmake SRCDIR' from there.")
|
|
endif()
|
|
|
|
|
|
# --- Compute relative path from bindir to srcdir
|
|
|
|
file(RELATIVE_PATH srcrel "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/foo")
|
|
string(REGEX REPLACE "/*foo$" "" srcrel "${srcrel}")
|
|
|
|
|
|
# --- Find Python
|
|
|
|
find_package(Python3 3.8 REQUIRED QUIET COMPONENTS Interpreter)
|
|
set(PYTHON3 "${Python3_EXECUTABLE}" CACHE STRING "Python 3 executable path")
|
|
message(STATUS "Using python executable: ${PYTHON3}")
|
|
|
|
|
|
# --- Compile lburg
|
|
|
|
add_executable(lburg lburg/lburg.c lburg/gram.c)
|
|
|
|
target_include_directories(lburg PUBLIC lburg)
|
|
|
|
|
|
# --- Run lburg
|
|
|
|
file(GLOB srcs_md CONFIGURE_DEPENDS
|
|
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.md" )
|
|
|
|
foreach(md ${srcs_md})
|
|
get_filename_component(mdn "${md}" NAME_WLE)
|
|
set(output "${mdn}.c")
|
|
list(APPEND srcs_lburg "${output}")
|
|
add_custom_command(OUTPUT "${output}"
|
|
COMMAND lburg "${srcrel}/src/${md}" "${output}"
|
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/src/${md}"
|
|
DEPENDS lburg VERBATIM)
|
|
endforeach()
|
|
|
|
|
|
# --- Compile cpp
|
|
|
|
add_executable(cpp
|
|
cpp/cpp.c cpp/lex.c cpp/nlist.c cpp/tokens.c cpp/macro.c cpp/eval.c
|
|
cpp/include.c cpp/hideset.c cpp/getopt.c cpp/unix.c )
|
|
|
|
target_include_directories(cpp PUBLIC cpp)
|
|
|
|
|
|
# --- Compile rcc
|
|
|
|
add_executable(rcc
|
|
src/alloc.c src/bind.c src/dag.c src/decl.c src/enode.c src/error.c
|
|
src/expr.c src/event.c src/init.c src/inits.c src/input.c src/lex.c
|
|
src/list.c src/main.c src/output.c src/prof.c src/profio.c
|
|
src/simp.c src/stmt.c src/string.c src/sym.c src/trace.c src/tree.c
|
|
src/types.c src/null.c src/symbolic.c src/stab.c src/gen.c src/bytecode.c
|
|
${srcs_lburg} )
|
|
|
|
target_include_directories(rcc PUBLIC src)
|
|
|
|
if ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
|
|
target_compile_options(rcc PRIVATE "-Wno-psabi")
|
|
endif()
|
|
|
|
|
|
# --- Compile lcc
|
|
|
|
add_executable(lcc
|
|
etc/lcc.c etc/gigatron-lcc.c )
|
|
|
|
target_compile_definitions(lcc PUBLIC
|
|
"-DTARGET=gigatron")
|
|
|
|
|
|
# --- Compile gtsim
|
|
|
|
add_executable(gtsim
|
|
gigatron/mapsim/gtsim.c )
|
|
|
|
|
|
# --- Stage binary directory to make glcc usable
|
|
|
|
set(gigatron_targets
|
|
glcc glink glink.py gtprof
|
|
interface.json interface-dev.json roms.json)
|
|
|
|
foreach(fn ${gigatron_targets})
|
|
set(output "${CMAKE_CURRENT_BINARY_DIR}/${fn}")
|
|
if ("${fn}" STREQUAL gtprof)
|
|
set(fn "mapsim/${fn}")
|
|
endif()
|
|
add_custom_command(OUTPUT "${output}"
|
|
COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${srcrel}/gigatron/${fn}" "${output}"
|
|
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/gigatron/${fn}"
|
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
VERBATIM)
|
|
endforeach()
|
|
|
|
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gigatron/glccver.py")
|
|
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/gigatron/glccver.py" ver)
|
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/glccver.py" "${ver}")
|
|
else()
|
|
set(ver "GLCC-unknown-version")
|
|
execute_process(COMMAND "git" "describe" "--tags"
|
|
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/glccver.py"
|
|
RESULT_VARIABLE status)
|
|
if ("${status}" STREQUAL "0")
|
|
file(READ "${CMAKE_CURRENT_BINARY_DIR}/glccver.py" ver)
|
|
string(STRIP "${ver}" ver)
|
|
endif()
|
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/glccver.py" "ver=\"${ver}\"\n")
|
|
endif()
|
|
|
|
if (WIN32)
|
|
foreach(fn glcc.cmd glink.cmd)
|
|
list(APPEND gigatron_targets "${fn}")
|
|
add_custom_command(OUTPUT "${fn}"
|
|
COMMAND "${CMAKE_COMMAND}" "-E" "echo" "@\"${PYTHON3}\" \"%~dp0\\%~n0\" %*" ">" "${fn}"
|
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
VERBATIM)
|
|
endforeach()
|
|
endif()
|
|
|
|
add_custom_target(glcc-ready ALL
|
|
COMMAND "${CMAKE_COMMAND}" "-E" "copy_directory" "${srcrel}/include/gigatron/" "include"
|
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
DEPENDS "cpp" "rcc" "lcc" ${gigatron_targets}
|
|
VERBATIM)
|
|
|
|
function(copy_target_to_bindir target)
|
|
add_custom_command(TARGET ${target} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:${target}>" "$<TARGET_FILE_NAME:${target}>"
|
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
VERBATIM)
|
|
endfunction()
|
|
|
|
copy_target_to_bindir(cpp)
|
|
copy_target_to_bindir(rcc)
|
|
copy_target_to_bindir(lcc)
|
|
copy_target_to_bindir(gtsim)
|
|
|
|
|
|
# --- Stage map directories
|
|
|
|
function(add_glcc_map mapname)
|
|
set(map_targets "")
|
|
file(GLOB mapfiles CONFIGURE_DEPENDS
|
|
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/gigatron/"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/gigatron/${mapname}/*.py")
|
|
foreach(fn ${mapfiles})
|
|
list(APPEND map_targets "${fn}")
|
|
add_custom_command(OUTPUT ${fn}
|
|
COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${srcrel}/gigatron/${fn}" "${fn}"
|
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/gigatron/${fn}"
|
|
VERBATIM )
|
|
endforeach()
|
|
add_custom_target("${mapname}" ALL
|
|
DEPENDS ${map_targets} VERBATIM)
|
|
endfunction()
|
|
|
|
file(GLOB gigatron_maps CONFIGURE_DEPENDS
|
|
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/gigatron/"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/gigatron/map*" )
|
|
foreach(map ${gigatron_maps})
|
|
add_glcc_map("${map}")
|
|
endforeach()
|
|
|
|
|
|
# ---- Compile gigatron libraries
|
|
|
|
# The previous version of add_glcc_library used to rely on
|
|
# add_custom_{command/target} to cross-compile the libraries. This
|
|
# works very well with the Makefile generators, but fails with the
|
|
# Visual Studio generator because only one of the command is
|
|
# executed. Whether this is a cmake bug or a msbuild bug is unclear.
|
|
#
|
|
# The following version takes a completely different approach.
|
|
# It builds a cmake script to cross-compile the library.
|
|
# This is less efficient but maybe more reliable.
|
|
|
|
function(add_glcc_library libname libfile)
|
|
# Parse the CPU x optional argument
|
|
set(cpulist 4 5 6 7)
|
|
list(GET ARGN 0 car)
|
|
if ("${car}" STREQUAL "CPU")
|
|
list(POP_FRONT ARGN car cpulist)
|
|
endif()
|
|
# Prepare the script
|
|
set(srclist "")
|
|
set(objlist "")
|
|
set(objdir "CMakeFiles/${libname}.glccdir")
|
|
set(script "${objdir}/${libname}.cmake")
|
|
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${objdir}")
|
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${script}" "
|
|
file(REMOVE \"${libfile}\")
|
|
set(glcccmd \".\\\\glcc.cmd\")
|
|
if (NOT EXISTS \"\${glcccmd}\")
|
|
set(glcccmd \"./glcc\")
|
|
endif()" )
|
|
if ("${CMAKE_GENERATOR}" MATCHES "Makefile")
|
|
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${script}" "
|
|
string(ASCII 27 esc)
|
|
set(COLORcyan \"\${esc}[36m\")
|
|
set(COLORreset \"\${esc}[m\")")
|
|
endif()
|
|
# Iterate over sources
|
|
foreach(fnp ${ARGN})
|
|
file(GLOB fn_list CONFIGURE_DEPENDS
|
|
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/${fnp}")
|
|
foreach(fn ${fn_list})
|
|
get_filename_component(fname "${fn}" NAME_WLE)
|
|
get_filename_component(fnext "${fn}" LAST_EXT)
|
|
list(APPEND srclist "${fn}")
|
|
if ("${fnext}" STREQUAL ".c")
|
|
foreach(cpu ${cpulist})
|
|
set(obj "${objdir}/${fname}_${cpu}.o")
|
|
list(APPEND objlist "${obj}")
|
|
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${script}" "
|
|
if (\"${srcrel}/${fn}\" IS_NEWER_THAN \"${obj}\")
|
|
message(\"\${COLORcyan}Cross-compiling ${obj}\${COLORreset}\")
|
|
execute_process(COMMAND \"\${glcccmd}\" \"-c\" \"-cpu=${cpu}\" \"-o\" \"${obj}\" \"${srcrel}/${fn}\"
|
|
WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\"
|
|
RESULT_VARIABLE status)
|
|
if (NOT \"\${status}\" EQUAL 0)
|
|
message(FATAL_ERROR \"Cross-compilation failed: \${status}\")
|
|
endif()
|
|
endif()
|
|
file(READ \"${obj}\" contents)
|
|
file(APPEND \"${libfile}\" \"\${contents}\")" )
|
|
endforeach()
|
|
elseif ("${fnext}" STREQUAL ".s")
|
|
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${script}" "
|
|
file(READ \"${srcrel}/${fn}\" contents)
|
|
file(APPEND \"${libfile}\" \"\${contents}\")" )
|
|
else()
|
|
message(FATAL_ERROR "Library file ${fname}${fext} has an unrecognized suffix")
|
|
endif()
|
|
endforeach()
|
|
endforeach()
|
|
# Create target
|
|
add_custom_target(${libname} ALL
|
|
COMMAND "${CMAKE_COMMAND}" } "-P" "${script}"
|
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
BYPRODUCTS ${objlist}
|
|
SOURCES ${srclist}
|
|
DEPENDS glcc-ready
|
|
VERBATIM)
|
|
endfunction()
|
|
|
|
add_glcc_library("libconx" "mapconx/libconx.a" "gigatron/mapconx/libconx/*.c")
|
|
add_glcc_library("libcon_b" "map512k/libcon_b.a" "gigatron/map512k/libcon_b/*.c" "gigatron/map512k/libcon_b/*.s")
|
|
add_glcc_library("libcon_n" "map512k/libcon_n.a" "gigatron/map512k/libcon_n/*.c" "gigatron/map512k/libcon_n/*.s")
|
|
add_glcc_library("libcon_h" "map512k/libcon_h.a" "gigatron/map512k/libcon_h/*.c" "gigatron/map512k/libcon_h/*.s")
|
|
add_glcc_library("libcon1" "map128k/libcon1.a" "gigatron/map128k/libcon1/*.c" "gigatron/map128k/libcon1/*.s")
|
|
add_glcc_library("libsim" "mapsim/libsim.a" "gigatron/mapsim/libsim/*.c" "gigatron/mapsim/libsim/*.s")
|
|
add_glcc_library("libc-cpu4" "cpu4/libc.a" CPU 4 "gigatron/libc/*.c" "gigatron/libc/*.s" "gigatron/runtime/*.s")
|
|
add_glcc_library("libc-cpu5" "cpu5/libc.a" CPU 5 "gigatron/libc/*.c" "gigatron/libc/*.s" "gigatron/runtime/*.s")
|
|
add_glcc_library("libc-cpu6" "cpu6/libc.a" CPU 6 "gigatron/libc/*.c" "gigatron/libc/*.s" "gigatron/runtime/*.s")
|
|
add_glcc_library("libc-cpu7" "cpu7/libc.a" CPU 7 "gigatron/libc/*.c" "gigatron/libc/*.s" "gigatron/runtime/*.s")
|
|
|
|
|
|
# ---- Installation
|
|
|
|
set(glcc_install_libdir "lib/gigatron-lcc")
|
|
set(glcc_install_bindir "bin")
|
|
|
|
install(TARGETS cpp rcc lcc gtsim
|
|
RUNTIME DESTINATION "${glcc_install_libdir}")
|
|
|
|
foreach(fn ${gigatron_targets})
|
|
get_filename_component(ext "${fn}" EXT)
|
|
if ("${ext}" STREQUAL ".json")
|
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${fn}"
|
|
DESTINATION "${glcc_install_libdir}")
|
|
else()
|
|
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${fn}"
|
|
DESTINATION "${glcc_install_libdir}")
|
|
endif()
|
|
endforeach()
|
|
|
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/glccver.py"
|
|
DESTINATION "${glcc_install_libdir}")
|
|
|
|
foreach(dn include cpu4 cpu5 cpu6 ${gigatron_maps})
|
|
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${dn}"
|
|
DESTINATION "${glcc_install_libdir}")
|
|
endforeach()
|
|
|
|
if (WIN32)
|
|
file(RELATIVE_PATH bin_to_lib "/${glcc_install_bindir}" "/${glcc_install_libdir}")
|
|
string(REPLACE "/" "\\\\" cmd_to_lib "${bin_to_lib}")
|
|
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory
|
|
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${glcc_install_bindir}\")")
|
|
foreach(pgm glcc glink gtsim gtprof)
|
|
set(pycmd "")
|
|
if (NOT "${pgm}" STREQUAL gtsim)
|
|
set(pycmd "\\\"${PYTHON3}\\\" ")
|
|
endif()
|
|
set(output "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${glcc_install_bindir}/${pgm}.cmd")
|
|
install(CODE "message(STATUS \"Installing: ${output}\")
|
|
execute_process(COMMAND ${CMAKE_COMMAND} -E echo
|
|
\"@${pycmd}\\\"%~dp0\\\\${cmd_to_lib}\\\\%~n0\\\" %*\"
|
|
OUTPUT_FILE \"${output}\") ")
|
|
endforeach()
|
|
else()
|
|
file(RELATIVE_PATH bin_to_lib "/${glcc_install_bindir}" "/${glcc_install_libdir}")
|
|
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory
|
|
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${glcc_install_bindir}\")")
|
|
foreach(pgm glcc glink gtsim gtprof)
|
|
set(output "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${glcc_install_bindir}/${pgm}")
|
|
install(CODE "message(STATUS \"Creating symlink: ${output}\")
|
|
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
|
|
\"${bin_to_lib}/${pgm}\" \"${output}\" )")
|
|
endforeach()
|
|
endif()
|