From 8bcbe24e98b4eb38cceb6a17ed1ac926be9c8f34 Mon Sep 17 00:00:00 2001
From: Alberto Nidasio <nidasioalberto@gmail.com>
Date: Fri, 16 Aug 2024 17:26:02 +0200
Subject: [PATCH] CMake build system now supports compiling with clang

Signed-off-by: Terraneo Federico <fede.tft@miosix.org>
---
 miosix/CMakeLists.txt                       | 18 ++++-
 miosix/_tools/kernel_global_objects.pl      | 13 +++-
 miosix/arch/cortexM4_stm32f4/CMakeLists.txt |  3 +
 miosix/arch/cortexM7_stm32f7/CMakeLists.txt |  3 +
 miosix/cmake/Toolchains/clang.cmake         | 75 +++++++++++++++++++++
 miosix/libsyscalls/CMakeLists.txt           | 22 +++++-
 6 files changed, 127 insertions(+), 7 deletions(-)
 create mode 100644 miosix/cmake/Toolchains/clang.cmake

diff --git a/miosix/CMakeLists.txt b/miosix/CMakeLists.txt
index e3209490..c2c0843d 100644
--- a/miosix/CMakeLists.txt
+++ b/miosix/CMakeLists.txt
@@ -137,7 +137,7 @@ target_link_options(miosix INTERFACE ${MIOSIX_L_FLAGS})
 # Run the kernel_global_objects.pl script on all kernel objects
 add_custom_command(
     TARGET miosix PRE_LINK
-    COMMAND perl ${MIOSIX_KPATH}/_tools/kernel_global_objects.pl $<TARGET_OBJECTS:miosix>
+    COMMAND perl ${MIOSIX_KPATH}/_tools/kernel_global_objects.pl $<TARGET_OBJECTS:miosix> --prefix=${MIOSIX_PREFIX}
     VERBATIM
     COMMAND_EXPAND_LISTS
 )
@@ -150,3 +150,19 @@ if(MIOSIX_PRINT_BOARD_LIST)
         message(STATUS "\t${MIOSIX_OPT_BOARD}")
     endforeach()
 endif()
+
+# Set multilib paths for Clang
+if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+    target_include_directories(miosix PUBLIC
+        /opt/arm-miosix-eabi/arm-miosix-eabi/include/c++/9.2.0/arm-miosix-eabi
+        /opt/arm-miosix-eabi/arm-miosix-eabi/include/c++/9.2.0
+        /opt/arm-miosix-eabi/arm-miosix-eabi/include
+    )
+
+    target_link_directories(miosix PUBLIC
+        /opt/arm-miosix-eabi/arm-miosix-eabi/lib/${MIOSIX_MULTILIB_PATH}
+        /opt/arm-miosix-eabi/lib/gcc/arm-miosix-eabi/9.2.0/${MIOSIX_MULTILIB_PATH}
+    )
+
+    target_link_options(miosix PUBLIC -fuse-ld=/usr/bin/arm-miosix-eabi-ld)
+endif()
diff --git a/miosix/_tools/kernel_global_objects.pl b/miosix/_tools/kernel_global_objects.pl
index 6bedf9a7..4f3d9801 100644
--- a/miosix/_tools/kernel_global_objects.pl
+++ b/miosix/_tools/kernel_global_objects.pl
@@ -37,6 +37,7 @@
 
 use warnings;
 use strict;
+use Getopt::Long;
 
 my $verbose=0; # Edit this file and set this to 1 for testing
 
@@ -44,16 +45,22 @@ my @files_with_global_objects;
 my @files_to_fix;
 my @files_broken;
 
+GetOptions(
+    "prefix=s" => \( my $prefix = "arm-miosix-eabi")
+);
+
 # Step #1: check all kernel object files and categorize them based on the
 # relevant sections
-foreach my $filename (@ARGV)
+foreach my $idx (0 .. $#ARGV)
 {
+	my $filename=$ARGV[$idx];
+
 	# First, check that the argument is really an object file
 	die "$filename is not a file name."    unless -f $filename;
 	die "$filename is not an object file." unless    $filename=~/\.o$/;
 
 	# Then use readelf to dump all sections of the file
-	my $output=`arm-miosix-eabi-readelf -SW \"$filename\"`;
+	my $output=`$prefix-readelf -SW \"$filename\"`;
 	my @lines=split("\n",$output);
 
 	my $sections=0;
@@ -98,7 +105,7 @@ foreach my $filename (@ARGV)
 # started, not after
 foreach my $filename (@files_to_fix)
 {
-	my $exitcode=system("arm-miosix-eabi-objcopy \"$filename\" --rename-section .init_array=.miosix_init_array");
+	my $exitcode=system("$prefix-objcopy \"$filename\" --rename-section .init_array=.miosix_init_array");
 	die "Error calling objcopy" unless($exitcode==0);
 }
 
diff --git a/miosix/arch/cortexM4_stm32f4/CMakeLists.txt b/miosix/arch/cortexM4_stm32f4/CMakeLists.txt
index e65ba72f..ba4b1708 100644
--- a/miosix/arch/cortexM4_stm32f4/CMakeLists.txt
+++ b/miosix/arch/cortexM4_stm32f4/CMakeLists.txt
@@ -35,6 +35,9 @@ include(${MIOSIX_KPATH}/arch/${MIOSIX_ARCH_NAME}/${MIOSIX_OPT_BOARD}/CMakeLists.
 # Automatically transform the architecture name into upper cases
 string(TOUPPER ${MIOSIX_ARCH_NAME} MIOSIX_ARCH_NAME_UPPER)
 
+# Set the path to the multilib directory for this architecture
+set(MIOSIX_MULTILIB_PATH thumb/v7e-m+fp/hard)
+
 # Select appropriate compiler flags for both ASM/C/C++/linker
 set(MIOSIX_CPU_FLAGS -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16)
 set(MIOSIX_A_FLAGS ${MIOSIX_CPU_FLAGS})
diff --git a/miosix/arch/cortexM7_stm32f7/CMakeLists.txt b/miosix/arch/cortexM7_stm32f7/CMakeLists.txt
index a0291e14..8284263b 100644
--- a/miosix/arch/cortexM7_stm32f7/CMakeLists.txt
+++ b/miosix/arch/cortexM7_stm32f7/CMakeLists.txt
@@ -35,6 +35,9 @@ include(${MIOSIX_KPATH}/arch/${MIOSIX_ARCH_NAME}/${MIOSIX_OPT_BOARD}/CMakeLists.
 # Automatically transform the architecture name into upper cases
 string(TOUPPER ${MIOSIX_ARCH_NAME} MIOSIX_ARCH_NAME_UPPER)
 
+# Set the path to the multilib directory for this architecture
+set(MIOSIX_MULTILIB_PATH thumb/v7e-m+dp/hard)
+
 # Select appropriate compiler flags for both C/C++/linker
 set(MIOSIX_A_FLAGS ${MIOSIX_CPU_FLAGS})
 list(APPEND MIOSIX_C_FLAGS
diff --git a/miosix/cmake/Toolchains/clang.cmake b/miosix/cmake/Toolchains/clang.cmake
new file mode 100644
index 00000000..41fdadd0
--- /dev/null
+++ b/miosix/cmake/Toolchains/clang.cmake
@@ -0,0 +1,75 @@
+# Copyright (C) 2024 by Skyward
+#
+# This program is free software; you can redistribute it and/or
+# it under the terms of the GNU General Public License as published
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered
+# by the GNU General Public License. However the source code for this
+# file must still be made available in accordance with the GNU
+# Public License. This exception does not invalidate any other
+# why a work based on this file might be covered by the GNU General
+# Public License.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>
+
+# Add the miosix/cmake path to find the Miosix.cmake platform file
+# that defines the Miosix system name
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/..)
+
+# Tell CMake that we are building for an embedded ARM system
+set(CMAKE_SYSTEM_NAME Miosix)
+
+set(MIOSIX_PREFIX      llvm)
+
+# Names of the compiler and other tools
+set(CMAKE_ASM_COMPILER clang)
+set(CMAKE_C_COMPILER   clang)
+set(CMAKE_CXX_COMPILER clang++)
+set(CMAKE_AR           ${MIOSIX_PREFIX}-ar)
+set(CMAKE_OBJCOPY      ${MIOSIX_PREFIX}-objcopy)
+set(CMAKE_OBJDUMP      ${MIOSIX_PREFIX}-objdump)
+set(CMAKE_SIZE         ${MIOSIX_PREFIX}-size)
+
+# Optimization flags for each language and build configuration
+set(CMAKE_ASM_FLAGS_DEBUG "")
+set(CMAKE_C_FLAGS_DEBUG "-g -O0")
+set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
+set(CMAKE_ASM_FLAGS_RELEASE "")
+set(CMAKE_C_FLAGS_RELEASE "-O2")
+set(CMAKE_CXX_FLAGS_RELEASE "-O2")
+set(CMAKE_ASM_FLAGS_RELWITHDEBINFO "")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -O2")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O2")
+set(CMAKE_ASM_FLAGS_MINSIZEREL "")
+set(CMAKE_C_FLAGS_MINSIZEREL "-Os")
+set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
+
+# Setting the target for crosscompilation
+# https://stackoverflow.com/questions/54539682/how-to-set-up-cmake-to-cross-compile-with-clang-for-arm-embedded-on-windows
+set(CLANG_TARGET_TRIPLE arm-none-eabi)
+set(CMAKE_ASM_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
+set(CMAKE_C_COMPILER_TARGET   ${CLANG_TARGET_TRIPLE})
+set(CMAKE_CXX_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
+
+set(CMAKE_SYSROOT /opt/arm-miosix-eabi/arm-miosix-eabi/lib)
+
+# We want to test for a static library and not an executable
+# reference: https://stackoverflow.com/questions/53633705/cmake-the-c-compiler-is-not-able-to-compile-a-simple-test-program
+set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
+
+# Defines used by the Miosix patches to the libraries/opt/arm-miosix-eabi/arm-miosix-eabi/lib/thumb/cm4/hardfp/fpv4sp
+add_compile_definitions($<$<COMPILE_LANGUAGE:C,CXX>:__GXX_TYPEINFO_EQUALITY_INLINE=0>)
+add_compile_definitions($<$<COMPILE_LANGUAGE:C,CXX>:_MIOSIX>)
+add_compile_definitions($<$<COMPILE_LANGUAGE:C,CXX>:_MIOSIX_GCC_PATCH_MAJOR=3>)
+add_compile_definitions($<$<COMPILE_LANGUAGE:C,CXX>:_MIOSIX_GCC_PATCH_MINOR=1>)
diff --git a/miosix/libsyscalls/CMakeLists.txt b/miosix/libsyscalls/CMakeLists.txt
index 92f5fd86..2bd22304 100644
--- a/miosix/libsyscalls/CMakeLists.txt
+++ b/miosix/libsyscalls/CMakeLists.txt
@@ -62,7 +62,7 @@ target_include_directories(syscalls PUBLIC
 set(MIOSIX_PROCESSES_A_FLAGS ${MIOSIX_CPU_FLAGS})
 set(MIOSIX_PROCESSES_C_FLAGS
     ${MIOSIX_CPU_FLAGS} -fpie -msingle-pic-base -ffunction-sections -Wall
-    -Werror=return-type -D_DEFAULT_SOURCE=1 -c
+    -fshort-enums -Werror=return-type -D_DEFAULT_SOURCE=1 -c
 )
 set(MIOSIX_PROCESSES_CXX_FLAGS -std=c++14 ${MIOSIX_OPT_EXCEPT} ${MIOSIX_PROCESSES_C_FLAGS})
 target_compile_options(syscalls PUBLIC
@@ -73,9 +73,25 @@ target_compile_options(syscalls PUBLIC
 
 # Configure linker file and options needed to link agains this library
 set(MIOSIX_PROCESSES_L_FLAGS
-    ${MIOSIX_CPU_FLAGS} -fpie -msingle-pic-base -nostdlib -Wl,--gc-sections
+    ${MIOSIX_CPU_FLAGS} -fpie -fshort-enums -msingle-pic-base -nostdlib -Wl,--gc-sections
     -Wl,-T${MIOSIX_KPATH}/libsyscalls/process.ld
-    -Wl,-n,-pie,--spare-dynamic-tags,3,--target2=mx-data-rel
+    -Wl,-n,-pie,--spare-dynamic-tags=3,--target2=mx-data-rel
 )
 set_property(TARGET syscalls PROPERTY LINK_DEPENDS ${MIOSIX_KPATH}/libsyscalls/process.ld)
 target_link_options(syscalls INTERFACE ${MIOSIX_PROCESSES_L_FLAGS})
+
+# Set multilib paths for Clang
+if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+    target_include_directories(syscalls PUBLIC
+        /opt/arm-miosix-eabi/arm-miosix-eabi/include/c++/9.2.0/arm-miosix-eabi
+        /opt/arm-miosix-eabi/arm-miosix-eabi/include/c++/9.2.0
+        /opt/arm-miosix-eabi/arm-miosix-eabi/include
+    )
+
+    target_link_directories(syscalls PUBLIC
+        /opt/arm-miosix-eabi/arm-miosix-eabi/lib/${MIOSIX_MULTILIB_PATH}/pie/single-pic-base/
+        /opt/arm-miosix-eabi/lib/gcc/arm-miosix-eabi/9.2.0/${MIOSIX_MULTILIB_PATH}/pie/single-pic-base/
+    )
+
+    target_link_options(miosix PUBLIC -fuse-ld=/usr/bin/arm-miosix-eabi-ld)
+endif()
-- 
GitLab