Commit 8920da3b authored by Christian Dietrich's avatar Christian Dietrich

cmake: simplify build system

remove some old cruft

Change-Id: Ie94b7dd352acec017979ce76fcc6d0f7fbd197b8
parent fcd30807
......@@ -29,18 +29,6 @@ endif()
include(${CMAKE_CURRENT_BINARY_DIR}/config.cmake)
list(REMOVE_DUPLICATES GENERATOR_ARGS)
if(GENERATOR_ARGS)
message(STATUS "[${PROJECT_NAME}] Additional Generator Arguments: ${GENERATOR_ARGS}")
string (REPLACE ";" " " _TMP_STR "${GENERATOR_ARGS}")
add_definitions(-DGENERATOR_ARGS="${_TMP_STR}")
else()
add_definitions(-DGENERATOR_ARGS="")
set(GENERATOR_ARGS "" CACHE STRING "")
endif()
option(FAIL_TRACE_ALL "Trace all binaries" OFF)
if(FAIL_TRACE_ALL)
message(STATUS "[${PROJECT_NAME}] Fail Trace All: ON")
......@@ -85,11 +73,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -include ${PROJECT_BINARY_DIR}/dosek_config.
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -include ${PROJECT_BINARY_DIR}/dosek_config.h")
list(REMOVE_DUPLICATES GENERATOR_ARGS)
# Documentation
add_subdirectory(toolchain/doxygen)
......
include(app)
#set(DOSEK_APPS "bcc1_tasks" CACHE STRING "Application(s) to compile (semicolon seperated)")
SUBDIRLIST(SUBDIRS ${CMAKE_CURRENT_SOURCE_DIR})
FOREACH(subdir ${SUBDIRS})
......
......@@ -14,18 +14,16 @@ add_subdirectory(platforms)
dosek_include_dir(${ARCH_INCLUDE_DIRS})
# Enable emulators
OPTION(ARM_TARGET_GEM5 "gem5" ON)
if(ARM_TARGET_GEM5)
set(ADDITIONAL_TARGETS ${ADDITIONAL_TARGETS}
${CMAKE_CURRENT_SOURCE_DIR}/gem5 CACHE INTERNAL STRING)
endif()
OPTION(ARM_TARGET_QEMU "QEMU" ON)
if(ARM_TARGET_QEMU)
set(ADDITIONAL_TARGETS ${ADDITIONAL_TARGETS}
# GEM5 is not well tested
# OPTION(ARM_TARGET_GEM5 "gem5" ON)
# if(ARM_TARGET_GEM5)
# set(ADDITIONAL_TARGETS ${ADDITIONAL_TARGETS}
# ${CMAKE_CURRENT_SOURCE_DIR}/gem5 CACHE INTERNAL STRING)
#endif()
# Add QEMU as an additional target
set(ADDITIONAL_TARGETS ${ADDITIONAL_TARGETS}
${CMAKE_CURRENT_SOURCE_DIR}/qemu CACHE INTERNAL STRING)
endif()
# setup ARM specific sources
......
......@@ -10,10 +10,7 @@ set(DEBUGGER "/srv/scratch/siflluka/gdb/gdb-7.7.1/gdb/gdb")
# Create additional targets for all executables
foreach(ELF ${EXECUTABLES})
GET_FILENAME_COMPONENT(SUFFIX ${ELF} NAME_WE)
set(DSUFFIX "-${SUFFIX}")
get_target_property(ELF_ABS ${ELF} LOCATION)
set(ELF_ABS ${PROJECT_BINARY_DIR}/${ELF})
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
......@@ -29,7 +26,7 @@ foreach(ELF ${EXECUTABLES})
set(GEM5_ARGS ${GEM5_CONFIG} --kernel ${ELF_ABS} --bootloader ${BOOTLOADER}) # --mem-size=${RAM_SIZE}MB
# Start gem5
add_custom_target(run${DSUFFIX}
add_custom_target(run-gem5-${ELF}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ELF} in gem5"
COMMAND ${GEM5} ${GEM5_ARGS}
......@@ -37,7 +34,7 @@ foreach(ELF ${EXECUTABLES})
)
# Start gem5 for tests (only serial console)
add_custom_target(test${DSUFFIX}
add_custom_target(test-gem5-${ELF}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ELF} in gem5 serial mode."
COMMAND ${GEM5} ${GEM5_ARGS} &
......@@ -46,7 +43,7 @@ foreach(ELF ${EXECUTABLES})
)
# Start gem5 and attach debugger
add_custom_target(debug${DSUFFIX}
add_custom_target(debug-gem5-${ELF}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ELF} in gem5 debug mode. "
COMMAND ${GEM5} ${GEM5_ARGS} &
......@@ -55,7 +52,7 @@ foreach(ELF ${EXECUTABLES})
)
# Start debugger attach to gem5
add_custom_target(debugger${DSUFFIX}
add_custom_target(debugger-gem5-${ELF}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Starting debugger for ${ELF}."
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
......
......@@ -10,34 +10,32 @@ set(QEMU_ARGS -M xilinx-zynq-a9 -m ${RAM_SIZE} -no-reboot -nographic -serial nul
# Create additional targets for all executables
foreach(ELF ${EXECUTABLES})
GET_FILENAME_COMPONENT(SUFFIX ${ELF} NAME_WE)
get_target_property(ELF_ABS ${ELF} LOCATION)
set(ELF_ABS ${PROJECT_BINARY_DIR}/${ELF})
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
# GDB init file
set(GDBINITFILE ${STARTUP_SCRIPTS}/${SUFFIX}.qemu.gdbinit)
set(GDBINITFILE ${STARTUP_SCRIPTS}/${ELF}.qemu.gdbinit)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/gdbinit.in" ${GDBINITFILE})
# Start QEMU
add_custom_target(qrun-${SUFFIX}
add_custom_target(run-${ELF}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in qemu-system-i386"
COMMAND ${QEMU} ${QEMU_ARGS} -kernel ${ELF_ABS}
)
# Start qemu for tests (only serial console)
add_custom_target(qtest-${SUFFIX}
add_custom_target(test-${ELF}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ELF} in qemu-system-arm no-graphic mode."
COMMAND ${QEMU} ${QEMU_ARGS} -kernel ${ELF_ABS}
)
# Start qemu and attach debugger
add_custom_target(qdebug-${SUFFIX}
add_custom_target(debug-${ELF}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ELF} in qemu-system-i386 debug mode. "
COMMAND ${QEMU} ${QEMU_ARGS} -kernel ${ELF_ABS} -gdb tcp::${DEBUG_PORT} -S &
......
# Get bochs binary
find_program(BOCHS "bochs")
if(NOT BOCHS)
message(WARNING "[${PROJECT_NAME}] No bochs found, not generating bochs targets!")
return()
endif()
# Create additional targets for all executables
foreach(ELF ${EXECUTABLES})
# Do not suffix targets for main executable
GET_FILENAME_COMPONENT(SUFFIX ${ELF} NAME_WE)
set(DSUFFIX "-${SUFFIX}")
get_target_property(ELF_ABS ${ELF} LOCATION)
set(ISOFILE "${ELF_ABS}.iso")
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
# Bochs
foreach(ELF ${EXECUTABLES})
set(BOCHS_BIOS "${CMAKE_CURRENT_SOURCE_DIR}/BIOS-bochs-latest")
set(BOCHS_GUEST_RAM ${RAM_SIZE})
set(BOCHS_HOST_RAM ${RAM_SIZE})
set(BOCHS_VGA_IMAGE "${CMAKE_CURRENT_SOURCE_DIR}/vgabios.bin")
set(BOCHS_ISO_IMAGE "${ISOFILE}")
set(BOCHS_ISO_IMAGE "${PROJECT_BINARY_DIR}/${ELF}.iso")
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
set(BOCHSRC "${STARTUP_SCRIPTS}/bochsrc${DSUFFIX}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc.in" ${BOCHSRC} )
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc-gdb.in" "${BOCHSRC}-gdb" )
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc-term.in" "${BOCHSRC}-term" )
set(BOCHSRC "${STARTUP_SCRIPTS}/bochsrc-${ELF}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc-nogui.in" "${BOCHSRC}-nogui" )
# GDB init file
set(GDBINITFILE ${STARTUP_SCRIPTS}/${SUFFIX}.gdbinit)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/gdbinit.in" ${GDBINITFILE})
# Start bochs
add_custom_target(run${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in Bochs."
COMMAND ${BOCHS} -f ${BOCHSRC}
)
# Start bochs in terminal (for ssh)
add_custom_target(runterm${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in Bochs term mode"
COMMAND ${BOCHS} -f ${BOCHSRC}-term
)
# Start bochs with GDB stub for debugging
add_custom_target(debug${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in Bochs with gdb"
COMMAND ${BOCHS} -f ${BOCHSRC}-gdb
)
# Start debugger attach to bochs
add_custom_target(debugger${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "Starting debugger for ${ISOFILE}..."
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
COMMAND ${DEBUGGER} -n -x ${GDBINITFILE} $<TARGET_FILE:${ELF}>
)
endforeach()
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
file @ELF@
set archi i386:x64-32:intel
target remote localhost:@DEBUG_PORT@
define pe
printf "[vc] %u - [B] %u - [D] %u %% [A] %u = %u (rem %u)\n", $arg0.vc, $arg0.B, $arg0.D, $arg0.A, (($arg0.vc - $arg0.B - $arg0.D) / $arg0.A), (($arg0.vc - $arg0.B - $arg0.D) % $arg0.A)
# Create additional targets for all executables
foreach(ELF ${EXECUTABLES})
# Do not suffix targets for main executable
GET_FILENAME_COMPONENT(SUFFIX ${ELF} NAME_WE)
set(DSUFFIX "-${SUFFIX}")
get_target_property(ELF_ABS ${ELF} LOCATION)
set(ISOFILE "${ELF_ABS}.iso")
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/grub/${SUFFIX}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
find_program(GRUB_MKRESCUE NAMES "grub-mkrescue" "grub2-mkrescue")
if(NOT GRUB_MKRESCUE)
message(WARNING "grub-mkrescue not found, cannot create bootable iso :(")
else(NOT GRUB_MKRESCUE)
foreach(ELF ${EXECUTABLES})
# Grub
find_program(GRUB_MKRESCUE NAMES "grub-mkrescue" "grub2-mkrescue")
if(NOT GRUB_MKRESCUE)
message(FATAL_ERROR "grub-mkrescue not found, cannot create bootable iso :(")
endif()
set(ISODIR "${PROJECT_BINARY_DIR}/grub/${SUFFIX}/grub_iso")
SET(ISODIR "${CMAKE_CURRENT_BINARY_DIR}/${ELF}")
# Generate build directory for grub-mkrescue
set(BOOTDIR "${ISODIR}/boot/")
set(GRUBDIR "${BOOTDIR}/grub")
......@@ -27,17 +15,11 @@ foreach(ELF ${EXECUTABLES})
file(COPY grub.cfg DESTINATION ${GRUBDIR})
# Create bootable ISO from ELF
add_custom_command(
add_custom_target(${ELF}.iso
DEPENDS ${ELF}
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${ELF}> ${BOOTDIR}/dosek.elf
COMMAND ${GRUB_MKRESCUE} -o ${ISOFILE} ${ISODIR}
COMMAND ${CMAKE_COMMAND} -E remove ${BOOTDIR}/dosek.elf
COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:${ELF}>" ${BOOTDIR}/dosek.elf
COMMAND ${GRUB_MKRESCUE} -o ${PROJECT_BINARY_DIR}/${ELF}.iso ${ISODIR}
COMMENT "[${PROJECT_NAME}] Generating bootable grub iso."
OUTPUT ${ISOFILE}
)
# Create bootable ISO
add_custom_target(iso${DSUFFIX}
DEPENDS ${ISOFILE}
)
endforeach()
endforeach()
endif()
......@@ -4,52 +4,47 @@ if(NOT QEMU)
message(WARNING "[${PROJECT_NAME} No QEMU found, not generating QEMU targets!")
return()
endif()
set(STARTUP_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
# Create additional targets for all executables
foreach(ELF ${EXECUTABLES})
GET_FILENAME_COMPONENT(SUFFIX ${ELF} NAME_WE)
set(DSUFFIX "-${SUFFIX}")
get_target_property(ELF_ABS ${ELF} LOCATION)
set(ISOFILE "${ELF_ABS}.iso")
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
set(ISOFILE "$<TARGET_FILE:${ELF}>.iso")
# Common arguments
set(QEMU_ARGS -kernel ${ELF_ABS} -no-reboot -machine pc,accel=tcg -m ${RAM_SIZE} -smp 2)
set(QEMU_ARGS -kernel ${PROJECT_BINARY_DIR}/${ELF} -no-reboot -machine pc,accel=tcg -m ${RAM_SIZE} -smp 2)
# GDB init file
# Fix whitespace escaping in CXX FLAGS
string(REPLACE ";" " " QEMU_ARGS_STR "${QEMU_ARGS}")
set(GDBINITFILE ${STARTUP_SCRIPTS}/${SUFFIX}.qemu.gdbinit)
set(ELF_ABS ${PROJECT_BINARY_DIR}/${ELF})
set(GDBINITFILE ${STARTUP_SCRIPTS}/${ELF}.qemu.gdbinit)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/gdbinit.in" ${GDBINITFILE})
# Start QEMU
add_custom_target(qrun${DSUFFIX}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ELF_ABS} in qemu-system-i386"
COMMAND ${QEMU} ${QEMU_ARGS}
)
# Start qemu in terminal (for ssh)
add_custom_target(qrunterm${DSUFFIX}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ELF_ABS} in qemu-system-i386 curses mode"
COMMAND ${QEMU} ${QEMU_ARGS} -display curses
)
# add_custom_target(run-${ELF}
# DEPENDS ${ELF}
# COMMENT "[${PROJECT_NAME}] Running $<TARGET_FILE:${ELF}> in qemu-system-i386"
# COMMAND ${QEMU} ${QEMU_ARGS}
# )
#
# # Start qemu in terminal (for ssh)
# add_custom_target(runterm-${ELF}
# DEPENDS ${ELF}
# COMMENT "[${PROJECT_NAME}] Running $<TARGET_FILE:${ELF}> in qemu-system-i386 curses mode"
# COMMAND ${QEMU} ${QEMU_ARGS} -display curses
# )
# Start qemu for tests (only serial console)
add_custom_target(qtest${DSUFFIX}
add_custom_target(test-${ELF}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ELF_ABS} in qemu-system-i386 no graphic mode."
COMMENT "[${PROJECT_NAME}] Running $<TARGET_FILE:${ELF}> in qemu-system-i386 no graphic mode."
COMMAND ${QEMU} ${QEMU_ARGS} -nographic
)
# Start qemu and attach debugger
add_custom_target(qdebug${DSUFFIX}
add_custom_target(debug-${ELF}
DEPENDS ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ELF} in qemu-system-i386 debug mode. "
COMMAND gdb -x "${GDBINITFILE}" ${ELF_ABS}
COMMAND gdb -x "${GDBINITFILE}" $<TARGET_FILE:${ELF}>
)
endforeach()
......@@ -216,8 +216,8 @@ macro(fail_test TEST TESTELF)
set(STATS_DICT ${DOSEK_OUTPUT_DIR}/stats.dict.py)
find_program(GIT "git")
add_custom_command(
DEPENDS ${ELF} iso-fail-${TEST} ${GIT_REV_FILE} fail-trace-plugin-python ${STATS_BINARY} ${STATS_TRACE}
COMMAND ${PYTHON} ${CHECK_WORKSPACE} -w ${PROJECT_SOURCE_DIR} -o ${PROJECT_BINARY_DIR}/.gitrev -g ${GIT}
DEPENDS ${ELF} fail-${TEST}.iso ${GIT_REV_FILE} fail-trace-plugin-python ${STATS_BINARY} ${STATS_TRACE}
# COMMAND ${PYTHON} ${CHECK_WORKSPACE} -w ${PROJECT_SOURCE_DIR} -o ${PROJECT_BINARY_DIR}/.gitrev -g ${GIT}
COMMAND ${CMAKE_COMMAND} -E remove_directory ${STATEDIR}
COMMAND ${FAIL_TRACE} -f ${BOCHSRC} -q
-Wf,--start-symbol=test
......
......@@ -24,5 +24,4 @@ add_executable(llvm-extractor main.cc)
# Link against LLVM libraries
target_link_libraries(llvm-extractor ${LLVM_LIBS} dl pthread curses)
GET_TARGET_PROPERTY(LLVM_EXTRACTOR_ llvm-extractor LOCATION)
SET(LLVM_EXTRACTOR ${LLVM_EXTRACTOR_} CACHE INTERNAL "")
SET(LLVM_EXTRACTOR "$<TARGET_FILE:llvm-extractor>" CACHE INTERNAL "")
......@@ -30,8 +30,6 @@ def main():
parser.add_option('-c', '--clean', dest='CLEAN', action="store_true",
default = False,
help="Remove all files from current directory before")
parser.add_option('', '--generator-args', dest='GENERATOR_ARGS', default = "",
help="Arguments for the system generator (default: )")
parser.add_option('-v', '--verbose', dest='verbose', action='count',
help="Increase verbosity (specify multiple times for more)")
parser.add_option('', '--fail-trace-all', dest='FAIL_TRACE_ALL', default = "no",
......@@ -63,7 +61,6 @@ def main():
logging.info("Specialized Systemcalls: %s", conf.os.specialize)
logging.info("State Asserts: %s", conf.dependability.state_asserts)
logging.info("Symbolic System Execution: %s", conf.os.passes.sse)
logging.info("Generator Arguments: %s", options.GENERATOR_ARGS)
logging.info("Fail Trace All: %s", options.FAIL_TRACE_ALL)
logging.info("Dependability Failure Logging: %s", conf.dependability.failure_logging)
......@@ -93,7 +90,6 @@ def main():
'-DCMAKE_TOOLCHAIN_FILE=%s' % toolchain_file,
"-DCMAKE_BUILD_TYPE=Release",
"-G", generator_dict[conf.generator],
"-DGENERATOR_ARGS='%s'"%options["GENERATOR_ARGS"],
"-DFAIL_TRACE_ALL=%s" % options["FAIL_TRACE_ALL"],
base_dir])
......
......@@ -25,7 +25,7 @@ MACRO(DOSEK_BINARY_EXECUTABLE NAME SOURCES SYSTEM_DESC VERIFY_SCRIPT DEFINITIONS
# Get the definitions to forward the ADD_DEFINITIONS to the
# application (e.g., -DENCODED)
get_directory_property(definitions DEFINITIONS)
get_directory_property(definitions COMPILE_DEFINITIONS)
separate_arguments(definitions)
# Fix whitespace escaping in CXX FLAGS
......
......@@ -7,8 +7,13 @@ SET(LLVM_RECOMMENDED_VERSION 3.4)
if(NOT DEFINED ${LLVM_ROOT})
# find llvm-config. prefers to the one with version suffix, Ex:llvm-config-3.4
find_program(LLVM_CONFIG_EXE NAMES "llvm-config" "llvm-config-${LLVM_RECOMMENDED_VERSION}"
HINTS /proj/i4danceos/tools/llvm-${LLVM_RECOMMENDED_VERSION}/bin)
# find llvm-config. prefers to the one with version suffix, Ex:llvm-config-3.4
find_program(LLVM_CONFIG_EXE NAMES "llvm-config-${LLVM_RECOMMENDED_VERSION}"
PATHS /proj/i4danceos/tools/llvm-${LLVM_RECOMMENDED_VERSION}/bin)
if (NOT LLVM_CONFIG_EXE)
find_program(LLVM_CONFIG_EXE NAMES "llvm-config"
PATHS /proj/i4danceos/tools/llvm-${LLVM_RECOMMENDED_VERSION}/bin)
endif()
# Get the directory of llvm by using llvm-config. also remove whitespaces.
execute_process(COMMAND ${LLVM_CONFIG_EXE} --prefix OUTPUT_VARIABLE LLVM_ROOT
......
......@@ -9,8 +9,12 @@ SET(LLVM_RECOMMENDED_VERSION 3.4)
if(NOT DEFINED ${LLVM_ROOT})
# find llvm-config. prefers to the one with version suffix, Ex:llvm-config-3.4
find_program(LLVM_CONFIG_EXE NAMES "llvm-config" "llvm-config-${LLVM_RECOMMENDED_VERSION}"
HINTS /proj/i4danceos/tools/llvm-${LLVM_RECOMMENDED_VERSION}/bin)
find_program(LLVM_CONFIG_EXE NAMES "llvm-config-${LLVM_RECOMMENDED_VERSION}"
PATHS /proj/i4danceos/tools/llvm-${LLVM_RECOMMENDED_VERSION}/bin)
if (NOT LLVM_CONFIG_EXE)
find_program(LLVM_CONFIG_EXE NAMES "llvm-config"
PATHS /proj/i4danceos/tools/llvm-${LLVM_RECOMMENDED_VERSION}/bin)
endif()
# Get the directory of llvm by using llvm-config. also remove whitespaces.
execute_process(COMMAND ${LLVM_CONFIG_EXE} --prefix OUTPUT_VARIABLE LLVM_ROOT
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment