[mono] Use more idiomatic cmake style (#82182)
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Tue, 21 Feb 2023 23:36:34 +0000 (18:36 -0500)
committerGitHub <noreply@github.com>
Tue, 21 Feb 2023 23:36:34 +0000 (18:36 -0500)
Make mono's build use a slightly more idiomatic `cmake` style:
* One `project()` per subdirectory, rather than just in `mini`
* toplevel `add_subdirectory` for each subdirectory
* specify sources relative to the current project source dir, rather than using `addprefix` to relativize everything from `mini`
* use object libraries for each logical grouping.  Set compile definitions, link libraries, etc on the object libraries.
* Have the final toplevel exes and shared libs (in mini; and components - when components are built to shared libs) pull in the object libraries. When building a static libmonosgen-2.0.a, pull in all the obejct libraries' objects to make a complete archive.

Doesn't untangle `src/mono/mono/components`  from `src/mono/moni/mini` yet, although things could be grouped better there too.

* make eglib into a cmake object library

   The goal is to use the cmake targets instead of _sources and _headers variables as well as to use the cmake add_subdirectory commands to bring in parts of the build

* make mono/utils into a cmake object library

* make sgen into a cmake object library

* make metadata into a cmake object library

* set MONO_DLL_EXPORT when building the object libraries

* add eglib_api target

   unlike eglib_objects, this one can be added by executables and static or shared libraries without pulling in the eglib sources.  This is what we want for dynamic runtime components, static interpreter and icall table libs, etc

* when building a static library, include all the ojects

   otherwise it would only include the mini objects - it's not transitive

* nit use target_compile_definitions for sgen

* log profiler links eglib objects, not just headers

* set project languages to C

   except for mini where we also enable CXX under some conditions (LLVM or ICU, or browser wasm)

* fix darwin framework builds

* fix for older cmake

   can't have sources directly on add_library(target INTERFACE ...)

* fix windows build

* remove unneeded define

   it's set later in the cmake file already

src/mono/mono/CMakeLists.txt
src/mono/mono/component/CMakeLists.txt
src/mono/mono/eglib/CMakeLists.txt
src/mono/mono/metadata/CMakeLists.txt
src/mono/mono/mini/CMakeLists.txt
src/mono/mono/profiler/CMakeLists.txt
src/mono/mono/sgen/CMakeLists.txt
src/mono/mono/utils/CMakeLists.txt

index 897a188..c594709 100644 (file)
@@ -1,6 +1,12 @@
 project(mono)
 
-set(subdirs mini profiler)
+set(subdirs
+  eglib
+  utils
+  sgen
+  metadata
+  mini
+  profiler)
 
 foreach(dir ${subdirs})
   add_subdirectory(${dir})
index ef815af..a47a380 100644 (file)
@@ -149,13 +149,15 @@ endif()
 foreach(component IN LISTS components)
   if(NOT DISABLE_COMPONENT_OBJECTS)
     add_library("${component}-objects" OBJECT "${${component}-sources}")
-    target_link_libraries("${component}-objects" component_base)
+    target_link_libraries("${component}-objects" PRIVATE component_base)
+    target_link_libraries("${component}-objects" PUBLIC eglib_api)
     foreach(dependency IN LISTS "${component}-dependencies")
       add_dependencies("${component}-objects" "${dependency}")
     endforeach()
   endif()
   add_library("${component}-stub-objects" OBJECT "${${component}-stub-sources}")
-  target_link_libraries("${component}-stub-objects" component_base)
+  target_link_libraries("${component}-stub-objects" PRIVATE component_base)
+  target_link_libraries("${component}-stub-objects" PUBLIC eglib_api)
 endforeach()
 
 if(NOT DISABLE_COMPONENTS AND NOT STATIC_COMPONENTS)
@@ -177,7 +179,7 @@ if(NOT DISABLE_COMPONENTS AND NOT STATIC_COMPONENTS)
     # FIXME: this is bad for things like the g_log_set_default_handler/g_logv
     # which use global state - we should move those functions into
     # monosgen-shared and get them via dynamic linking.
-    target_sources("mono-component-${component}" PRIVATE $<TARGET_OBJECTS:eglib_objects>)
+    target_link_libraries("mono-component-${component}" PRIVATE eglib_objects)
     if(NOT DISABLE_SHARED_LIBS)
       # If we disable shared libs, but build dynamic components we would need
       # to enable allowing undefined symbols here (presumably to be resolved
index a9bc6f2..3de4a9c 100644 (file)
@@ -1,3 +1,4 @@
+project(eglib C)
 
 set(eglib_win32_sources
     gdate-win32.c gdir-win32.c gfile-win32.c gmisc-win32.c
@@ -14,16 +15,13 @@ set(eglib_platform_sources ${eglib_unix_sources})
 endif()
 
 set(eglib_common_sources
-    eglib-remap.h
     sort.frag.h
-    glib.h
     garray.c
     gbytearray.c
     gerror.c
     ghashtable.c
     giconv.c
     gmem.c
-    gmodule.h
     goutput.c
     gstr.c
     gslist.c
@@ -37,10 +35,25 @@ set(eglib_common_sources
     gfile-posix.c
     gutf8.c)
 
+set(eglib_headers
+  glib.h
+  eglib-remap.h
+  gmodule.h)
+
 if(HAVE_CLOCK_NANOSLEEP)
 list(APPEND eglib_common_sources gclock-nanosleep.c)
 endif()
 
-addprefix(eglib_sources ../eglib/ "${eglib_platform_sources};${eglib_common_sources}")
+set(eglib_sources "${eglib_platform_sources};${eglib_common_sources}")
+
+add_library(eglib_api INTERFACE)
+target_sources(eglib_api INTERFACE ${eglib_headers})
+# to pick up eglib-config.h and glib.h, respectively
+target_include_directories(eglib_api INTERFACE ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR})
 
 add_library(eglib_objects OBJECT "${eglib_sources}")
+# to pick up config.h, and the eglib headers, respectively
+target_include_directories(eglib_objects PRIVATE
+  ${PROJECT_BINARY_DIR}/../..
+  ${PROJECT_SOURCE_DIR})
+target_link_libraries (eglib_objects PUBLIC eglib_api)
index 797637a..abddf1a 100644 (file)
@@ -1,9 +1,14 @@
+project(metadata C)
+
 #
 # This library contains the icall tables if the runtime was configured with DISABLE_ICALL_TABLES
 #
 if(DISABLE_ICALL_TABLES)
-add_library(mono-icall-table STATIC "../metadata/icall-table.c")
-target_link_libraries(mono-icall-table monoapi)
+add_library(mono-icall-table STATIC "icall-table.c")
+target_link_libraries(mono-icall-table PRIVATE monoapi eglib_api)
+target_include_directories(mono-icall-table PRIVATE ${PROJECT_BINARY_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/..)
 install(TARGETS mono-icall-table LIBRARY)
 else()
 set(icall_table_sources "icall-table.c")
@@ -191,9 +196,16 @@ elseif(MONO_GC STREQUAL "boehm")
     set(metadata_compile_definitions "HAVE_BOEHM_GC")
 endif()
 
-addprefix(metadata_gc_dependent_real_sources ../metadata "${metadata_gc_dependent_sources}")
-addprefix(metadata_gc_real_sources ../metadata "${metadata_gc_sources}")
-addprefix(ilgen_real_sources ../metadata "${ilgen_sources}")
-set_source_files_properties(${metadata_gc_real_sources};${metadata_gc_dependent_real_sources};${ilgen_real_sources} PROPERTIES COMPILE_DEFINITIONS "${metadata_compile_definitions}")
+set(metadata_sources "${metadata_platform_sources};${metadata_common_sources};${metadata_gc_dependent_sources};${metadata_gc_sources};${ilgen_sources}")
+
+add_library(metadata_objects OBJECT ${metadata_sources})
+target_compile_definitions(metadata_objects PRIVATE ${metadata_compile_definitions})
+target_link_libraries(metadata_objects PRIVATE monoapi eglib_api utils_objects)
+# note: metadata_objects is an object library, so this doesn't force linking with sgen,
+# it just adds the relevant include directories - which we need even with Boehm
+target_link_libraries(metadata_objects PRIVATE sgen_objects)
+target_compile_definitions(metadata_objects PRIVATE -DMONO_DLL_EXPORT)
+target_include_directories(metadata_objects PRIVATE ${PROJECT_BINARY_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/..)
 
-addprefix(metadata_sources ../metadata/ "${metadata_platform_sources};${metadata_common_sources};${metadata_gc_dependent_sources};${metadata_gc_sources};${ilgen_sources}")
index 0ea1d8f..96887f8 100644 (file)
@@ -1,15 +1,17 @@
-project(mini)
+project(mini C)
+
+if(ENABLE_LLVM OR ENABLE_LLVM_RUNTIME OR HOST_BROWSER OR (HAVE_SYS_ICU AND NOT HOST_WASI))
+  enable_language(CXX)
+endif()
 
 include(FindPython3)
 
 include_directories(
   ${PROJECT_BINARY_DIR}/
   ${PROJECT_BINARY_DIR}/../..
-  ${PROJECT_BINARY_DIR}/../../mono/eglib
   ${CMAKE_CURRENT_SOURCE_DIR}/../..
   ${PROJECT_SOURCE_DIR}/../
-  ${PROJECT_SOURCE_DIR}/../eglib
-  ${PROJECT_SOURCE_DIR}/../sgen)
+  )
 
 if(HOST_DARWIN)
   set(OS_LIBS "-framework CoreFoundation" "-framework Foundation")
@@ -34,10 +36,6 @@ endif()
 #
 # SUBDIRS
 #
-include(../eglib/CMakeLists.txt)
-include(../utils/CMakeLists.txt)
-include(../metadata/CMakeLists.txt)
-include(../sgen/CMakeLists.txt)
 include(../component/CMakeLists.txt)
 
 if(HOST_WIN32)
@@ -297,7 +295,10 @@ endif()
 
 if(ENABLE_INTERP_LIB)
 add_library(mono-ee-interp STATIC "${interp_sources}")
-target_link_libraries(mono-ee-interp monoapi)
+target_link_libraries(mono-ee-interp monoapi eglib_api)
+target_include_directories(mono-ee-interp PRIVATE ${PROJECT_BINARY_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/..)
 install(TARGETS mono-ee-interp LIBRARY)
 if(HOST_WASM AND CMAKE_BUILD_TYPE STREQUAL "Debug")
 # Always optimize the interpreter, even in Debug builds.  Unoptimized interp_exec_method and
@@ -348,12 +349,11 @@ if(HOST_WIN32)
 set_source_files_properties(${ZLIB_SOURCES} PROPERTIES COMPILE_OPTIONS "/wd4005;/wd4127;/wd4131;/wd4244")
 endif()
 
-set(monosgen-sources "${metadata_sources};${utils_sources};${sgen_sources};${icu_shim_sources};${mini_sources};${ZLIB_SOURCES}")
+set(monosgen-sources "${icu_shim_sources};${mini_sources};${ZLIB_SOURCES}")
 
 add_library(monosgen-objects OBJECT "${monosgen-sources}")
-target_link_libraries (monosgen-objects PRIVATE monoapi)
-add_library(monosgen-static STATIC $<TARGET_OBJECTS:monosgen-objects>;$<TARGET_OBJECTS:eglib_objects>)
-target_link_libraries (monosgen-static PRIVATE monoapi)
+target_link_libraries (monosgen-objects PRIVATE monoapi eglib_api utils_objects sgen_objects metadata_objects)
+add_library(monosgen-static STATIC $<TARGET_OBJECTS:eglib_objects> $<TARGET_OBJECTS:utils_objects> $<TARGET_OBJECTS:sgen_objects> $<TARGET_OBJECTS:metadata_objects> $<TARGET_OBJECTS:monosgen-objects>)
 set_target_properties(monosgen-static PROPERTIES OUTPUT_NAME ${MONO_LIB_NAME})
 
 if(DISABLE_COMPONENTS OR AOT_COMPONENTS)
@@ -372,13 +372,12 @@ if(NOT DISABLE_SHARED_LIBS)
     add_library(monosgen-shared SHARED $<TARGET_OBJECTS:monosgen-objects>)
     target_compile_definitions(monosgen-objects PRIVATE -DMONO_DLL_EXPORT)
   endif()
-  target_sources(monosgen-shared PRIVATE $<TARGET_OBJECTS:eglib_objects>)
   # Alpine Linux implements ucontext in a different library
   if(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
     target_link_libraries(monosgen-shared PRIVATE ucontext)
   endif(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
   set_target_properties(monosgen-shared PROPERTIES OUTPUT_NAME ${MONO_SHARED_LIB_NAME})
-  target_link_libraries (monosgen-shared PRIVATE monoapi)
+  target_link_libraries(monosgen-shared PRIVATE monoapi eglib_objects utils_objects sgen_objects metadata_objects)
   target_include_directories (monosgen-shared PRIVATE monoapi)
   if(TARGET_WIN32)
     # on Windows the import library for the shared mono library will have the same name as the static library,
@@ -413,7 +412,7 @@ if(NOT DISABLE_SHARED_LIBS)
   install(TARGETS monosgen-shared LIBRARY)
   if(HOST_WIN32 AND TARGET_AMD64)
     add_library(monosgen-shared-dac SHARED "mini-windows-dlldac.c")
-    target_link_libraries(monosgen-shared-dac monoapi)
+    target_link_libraries(monosgen-shared-dac monoapi eglib_api)
     set_target_properties(monosgen-shared-dac PROPERTIES OUTPUT_NAME ${MONO_SHARED_LIB_NAME}-dac)
   endif()
 
@@ -435,8 +434,9 @@ if(NOT DISABLE_SHARED_LIBS)
         endif()
         add_library(${frameworkconfig} SHARED $<TARGET_OBJECTS:monosgen-objects>)
         target_compile_definitions(${frameworkconfig} PRIVATE -DMONO_DLL_EXPORT)
-        target_sources(${frameworkconfig} PRIVATE $<TARGET_OBJECTS:eglib_objects>)
+        target_link_libraries(${frameworkconfig} PRIVATE monoapi eglib_objects utils_objects sgen_objects metadata_objects)
         target_link_libraries(${frameworkconfig} PRIVATE ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS})
+
         if(ICU_LDFLAGS)
           set_property(TARGET ${frameworkconfig} APPEND_STRING PROPERTY LINK_FLAGS " ${ICU_LDFLAGS}")
         endif()
@@ -463,10 +463,10 @@ if(HOST_BROWSER)
   # Add two static libs containing llvm-runtime.cpp compiled for JS based/WASM EH
   # This is the only source file which contains a c++ throw or catch
   add_library(mono-wasm-eh-js STATIC llvm-runtime.cpp)
-  target_link_libraries (mono-wasm-eh-js PRIVATE monoapi)
+  target_link_libraries (mono-wasm-eh-js PRIVATE monoapi eglib_api)
   install(TARGETS mono-wasm-eh-js LIBRARY)
   add_library(mono-wasm-eh-wasm STATIC llvm-runtime.cpp)
-  target_link_libraries (mono-wasm-eh-wasm PRIVATE monoapi)
+  target_link_libraries (mono-wasm-eh-wasm PRIVATE monoapi eglib_api)
   set_target_properties(mono-wasm-eh-wasm PROPERTIES COMPILE_FLAGS "-fwasm-exceptions")
   install(TARGETS mono-wasm-eh-wasm LIBRARY)
 endif()
@@ -539,7 +539,7 @@ if(NOT DISABLE_EXECUTABLES)
   if(MONO_CROSS_COMPILE_EXECUTABLE_NAME)
     set_target_properties(mono-sgen PROPERTIES OUTPUT_NAME mono-aot-cross)
   endif()
-  target_link_libraries(mono-sgen PRIVATE monoapi monosgen-static ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS})
+  target_link_libraries(mono-sgen PRIVATE monoapi eglib_api monosgen-static ${OS_LIBS} ${LLVM_LIBS} ${ICU_LIBS} ${Z_LIBS})
   # Alpine Linux implements ucontext in a different library
   if(CLR_CMAKE_HOST_ALPINE_LINUX AND TARGET_S390X)
     target_link_libraries(mono-sgen PRIVATE ucontext)
index b2a3d3c..f556eac 100644 (file)
@@ -14,7 +14,7 @@ if(NOT DISABLE_LIBS)
     # Build the logging profiler only for certain platforms
     add_library(mono-profiler-log SHARED helper.c log.c log-args.c ${ZLIB_SOURCES})
     target_compile_definitions(mono-profiler-log PRIVATE -DMONO_DLL_EXPORT)
-    target_link_libraries(mono-profiler-log monosgen-shared eglib_objects monoapi)
+    target_link_libraries(mono-profiler-log monosgen-shared monoapi eglib_objects)
     if(HOST_ANDROID)
       target_link_libraries(mono-profiler-log log)
     endif()
index 31c582f..8297a87 100644 (file)
@@ -1,3 +1,5 @@
+project (sgen C)
+
 if(NOT MONO_GC STREQUAL "sgen")
     return()
 endif()
@@ -55,5 +57,11 @@ set(sgen_sources_base
     sgen-workers.c
     sgen-workers.h)
 
-addprefix(sgen_sources ../sgen/ "${sgen_sources_base}")
-set_source_files_properties(${sgen_sources} PROPERTIES COMPILE_DEFINITIONS "HAVE_SGEN_GC")
+set(sgen_sources "${sgen_sources_base}")
+
+add_library(sgen_objects ${sgen_sources})
+target_link_libraries(sgen_objects PRIVATE monoapi eglib_api utils_objects)
+target_compile_definitions(sgen_objects PRIVATE -DMONO_DLL_EXPORT -DHAVE_SGEN_GC)
+target_include_directories(sgen_objects PRIVATE ${PROJECT_BINARY_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/..)
index 69c5a3c..5d6544b 100644 (file)
@@ -1,3 +1,4 @@
+project(utils C)
 
 set(utils_win32_sources
     mono-os-semaphore-win32.c
@@ -230,7 +231,7 @@ else()
   message(FATAL_ERROR "")
 endif()
 
-addprefix(utils_sources ../utils/ "${utils_platform_sources};${utils_arch_sources};${utils_common_sources}")
+set(utils_sources "${utils_platform_sources};${utils_arch_sources};${utils_common_sources}")
 
 set(utils_sources
     ${utils_sources}
@@ -259,3 +260,11 @@ if(ENABLE_DTRACE)
 
     set(utils_sources "${utils_sources};${CMAKE_CURRENT_LIST_DIR}/mono-dtrace.h;../utils/dtrace.h")
 endif()
+
+add_library(utils_objects OBJECT ${utils_sources})
+target_link_libraries(utils_objects PRIVATE monoapi eglib_api)
+target_compile_definitions(utils_objects PRIVATE -DMONO_DLL_EXPORT)
+target_include_directories(utils_objects PRIVATE ${PROJECT_BINARY_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/../..
+  ${PROJECT_SOURCE_DIR}/..)
+