forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request dotnet#2108 from vargaz/mono-cmake-build
Initial CMAKE build system support for Mono.
- Loading branch information
Showing
13 changed files
with
3,131 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
cmake_minimum_required (VERSION 3.10) | ||
|
||
project (mono) | ||
|
||
include(GNUInstallDirs) | ||
include(CheckIncludeFile) | ||
include(CheckFunctionExists) | ||
include(TestBigEndian) | ||
|
||
set(CMAKE_MODULE_PATH | ||
${CMAKE_MODULE_PATH} | ||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake" | ||
) | ||
|
||
find_program(CCACHE_PROGRAM ccache) | ||
if(CCACHE_PROGRAM) | ||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") | ||
endif() | ||
|
||
function(append value) | ||
foreach(variable ${ARGN}) | ||
set(${variable} "${${variable}} ${value}" PARENT_SCOPE) | ||
endforeach(variable) | ||
endfunction() | ||
|
||
# User options | ||
include(options) | ||
# Header/function checks | ||
include(configure) | ||
|
||
# FIXME: | ||
set(VERSION "") | ||
|
||
execute_process( | ||
COMMAND grep ^MONO_CORLIB_VERSION= configure.ac | ||
COMMAND cut -d = -f 2 | ||
OUTPUT_VARIABLE CORLIB_VERSION_OUT | ||
) | ||
if (CORLIB_VERSION_OUT STREQUAL "") | ||
message(FATAL_ERROR) | ||
endif() | ||
string(STRIP "${CORLIB_VERSION_OUT}" MONO_CORLIB_VERSION_BASE) | ||
set(MONO_CORLIB_VERSION "\"${MONO_CORLIB_VERSION_BASE}\"") | ||
|
||
if (ENABLE_NETCORE) | ||
set(DISABLE_REMOTING 1) | ||
set(DISABLE_REFLECTION_EMIT_SAVE 1) | ||
set(DISABLE_APPDOMAINS 1) | ||
set(DISABLE_CLEANUP 1) | ||
set(DISABLE_ASSEMBLY_REMAPPING 1) | ||
set(DISABLE_SECURITY 1) | ||
set(DISABLE_MDB 1) | ||
set(DISABLE_COM 1) | ||
set(DISABLE_GAC 1) | ||
set(DISABLE_PERFCOUNTERS 1) | ||
set(DISABLE_ATTACH 1) | ||
set(DISABLE_DLLMAP 1) | ||
else() | ||
message(FATAL_ERROR "Building without -DENABLE_NETCORE=1 is not supported.") | ||
endif() | ||
|
||
#FIXME: | ||
set(VERSION "\"\"") | ||
set(DISABLED_FEATURES "\"\"") | ||
|
||
if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")) | ||
set (GCC 1) | ||
endif () | ||
|
||
add_definitions(-g) | ||
add_definitions(-DHAVE_CONFIG_H) | ||
add_definitions(-D_THREAD_SAFE) | ||
|
||
if (GCC) | ||
add_definitions(-fPIC) | ||
add_definitions(-DMONO_DLL_EXPORT) | ||
add_definitions(-fvisibility=hidden) | ||
endif() | ||
|
||
set(USE_GCC_ATOMIC_OPS 1) | ||
set(HAVE_CLASSIC_WINAPI_SUPPORT 1) | ||
set(ENABLE_ILGEN 1) | ||
set(HAVE_MOVING_COLLECTOR 1) | ||
set(HAVE_CONC_GC_AS_DEFAULT 1) | ||
set(MONO_INSIDE_RUNTIME 1) | ||
|
||
###################################### | ||
# GCC CHECKS | ||
###################################### | ||
if(GCC) | ||
# We require C99 with some GNU extensions, e.g. `linux` macro | ||
add_definitions(-std=gnu99) | ||
# The runtime code does not respect ANSI C strict aliasing rules | ||
append("-fno-strict-aliasing" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) | ||
# We rely on signed overflow to behave | ||
append("-fwrapv" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) | ||
|
||
set(WARNINGS "-Wall -Wunused -Wmissing-declarations -Wpointer-arith -Wno-cast-qual -Wwrite-strings -Wno-switch -Wno-switch-enum -Wno-unused-value -Wno-attributes -Qunused-arguments -Wno-unused-function -Wno-tautological-compare -Wno-parentheses-equality -Wno-self-assign -Wno-return-stack-address -Wno-constant-logical-operand -Wno-zero-length-array -Wmissing-prototypes -Wstrict-prototypes -Wnested-externs -Wno-format-zero-length") | ||
|
||
set(WERROR "-Werror=incompatible-pointer-types -Werror=return-type -Werror-implicit-function-declaration") | ||
|
||
append("${WARNINGS} ${WERROR}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) | ||
endif() | ||
|
||
###################################### | ||
# HOST OS CHECKS | ||
###################################### | ||
|
||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") | ||
add_definitions(-D_THREAD_SAFE) | ||
set(HOST_DARWIN 1) | ||
set(PTHREAD_POINTER_ID 1) | ||
set(USE_MACH_SEMA 1) | ||
else() | ||
message(FATAL ERROR "") | ||
endif() | ||
|
||
###################################### | ||
# TARGET OS CHECKS | ||
###################################### | ||
|
||
# FIXME: | ||
set(TARGET_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}") | ||
|
||
if(TARGET_SYSTEM_NAME STREQUAL "Darwin") | ||
set(TARGET_MACH 1) | ||
set(TARGET_OSX 1) | ||
set(RID_PREFIX "osx") | ||
set(CORETARGETS "-p:TargetsUnix=true -p:TargetsOSX=true") | ||
set(NETCORE_HOST_PLATFORM "macos") | ||
else() | ||
message(FATAL ERROR "") | ||
endif() | ||
|
||
###################################### | ||
# HOST ARCH CHECKS | ||
###################################### | ||
|
||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") | ||
set(HOST_AMD64 1) | ||
else() | ||
message(FATAL ERROR "") | ||
endif() | ||
|
||
###################################### | ||
# TARGET ARCH CHECKS | ||
###################################### | ||
# FIXME: | ||
set(TARGET_ARCH "${CMAKE_SYSTEM_PROCESSOR}") | ||
|
||
if(TARGET_ARCH STREQUAL "x86_64") | ||
set(TARGET_AMD64 1) | ||
set(MONO_ARCHITECTURE "\"amd64\"") | ||
set(RID_SUFFIX "x64") | ||
set(COREARCH "x64") | ||
else() | ||
message(FATAL ERROR "") | ||
endif() | ||
|
||
###################################### | ||
# EGLIB CHECKS | ||
###################################### | ||
|
||
set (GNUC_PRETTY) | ||
set (GNUC_UNUSED) | ||
set (BREAKPOINT "G_STMT_START { raise (SIGTRAP); } G_STMT_END") | ||
if (GCC) | ||
set (GNUC_UNUSED "__attribute__((__unused__))") | ||
set (GNUC_NORETURN "__attribute__((__noreturn__))") | ||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86|x86_64") | ||
set (BREAKPOINT "G_STMT_START { __asm__ (\"int \$03\"); } G_STMT_END") | ||
endif () | ||
endif () | ||
|
||
if (IS_BIG_ENDIAN) | ||
set (ORDER G_BIG_ENDIAN) | ||
else () | ||
set (ORDER G_LITTLE_ENDIAN) | ||
endif () | ||
|
||
if (WIN32) | ||
# FIXME: | ||
message (FATAL_ERROR "FIXME") | ||
else () | ||
set(PATHSEP "/") | ||
set(SEARCHSEP ":") | ||
set(OS "UNIX") | ||
set(PIDTYPE "int") | ||
endif () | ||
|
||
# FIXME: | ||
set(GSIZE_FORMAT "\"lu\"") | ||
|
||
set(GSIZE "size_t") | ||
set(GSSIZE "ptrdiff_t") | ||
|
||
# | ||
# END OF EGLIB CHECKS | ||
# | ||
|
||
TEST_BIG_ENDIAN (IS_BIG_ENDIAN) | ||
|
||
# FIXME: | ||
set(TARGET_SIZEOF_VOID_P "${SIZEOF_VOID_P}") | ||
set(SIZEOF_REGISTER "${SIZEOF_VOID_P}") | ||
|
||
if (IS_BIG_ENDIAN) | ||
set(TARGET_BYTE_ORDER G_BIG_ENDIAN) | ||
else() | ||
set(TARGET_BYTE_ORDER G_LITTLE_ENDIAN) | ||
endif() | ||
|
||
set (RID "${RID_PREFIX}-${RID_SUFFIX}") | ||
|
||
add_subdirectory (mono) | ||
|
||
configure_file (cmake/config.h.in config.h) | ||
configure_file (cmake/eglib-config.h.cmake.in mono/eglib/eglib-config.h) | ||
configure_file (cmake/netcore-config.make.in netcore/config.make) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Introduction | ||
|
||
* This is an alternative CMAKE based build system for mono. | ||
* The autoconf build system is still the official one. | ||
* Only a subset of platforms/configurations etc. are supported. | ||
|
||
# Usage | ||
|
||
```cmake -DENABLE_NETCORE=1 -G Ninja .``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#!/usr/bin/env python3 | ||
import sys | ||
import argparse | ||
import subprocess | ||
|
||
# | ||
# Tool to extract configure.ac defines/checks from configure.ac for use with cmake. | ||
# --autoheader -> generate a cmake style config.h.in | ||
# --emit-cmake -> generate a starting cmake file | ||
# | ||
|
||
parser = argparse.ArgumentParser (prefix_chars = '-') | ||
parser.add_argument('--autoheader', metavar='FILENAME', help='emit a config.h.in file') | ||
parser.add_argument('--emit-cmake', metavar='FILENAME', help='emit a list of possible variables/configure options') | ||
parser.add_argument('--filter-defines', metavar='FILENAME', help='list of defines to keep') | ||
parser.add_argument('filename', help='path to configure.ac') | ||
args = parser.parse_args () | ||
|
||
if args.filename == None: | ||
parser.print_help () | ||
sys.exit (1) | ||
|
||
if args.autoheader == None and args.emit_cmake == None: | ||
sys.stderr.write ("At least one of --autoheader/--emit-cmake is required.") | ||
sys.exit (1) | ||
|
||
used_defines = None | ||
if args.filter_defines != None: | ||
used_defines = {} | ||
with open (args.filter_defines) as f: | ||
for line in f: | ||
line = line.strip () | ||
used_defines [line] = 1 | ||
|
||
#'/usr/local/Cellar/autoconf/2.69/bin/autom4te' --language=autoconf --verbose --trace AC_CONFIG_HEADERS:'$$config_h ||= '"'"'$1'"'"';' --trace AH_OUTPUT:'A: $1 B $2 C;' --trace AC_DEFINE_TRACE_LITERAL:'$$symbol{'"'"'$1'"'"'} = 1;' configure.ac | ||
|
||
# Generate a python script from configure.ac | ||
proc = subprocess.Popen (["autom4te", "--language=autoconf", "--verbose", "--trace", "AH_OUTPUT:defs['$1'] = \"\"\"$2\"\"\"\n", "--trace", "AC_CHECK_HEADER:headers['$1'] = 1\n", "--trace", "AC_CHECK_HEADERS:headers['$1'] = 1\n", "--trace", "AC_CHECK_FUNCS:funcs['$1'] = 1\n", args.filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) | ||
outs, errs = proc.communicate () | ||
if proc.returncode != 0: | ||
print (errs) | ||
sys.exit (1) | ||
|
||
with open ('tmp.py', 'w') as f: | ||
f.write ('defs = {}\n') | ||
f.write ('headers = {}\n') | ||
f.write ('funcs = {}\n') | ||
f.write (outs) | ||
|
||
# Process it | ||
import tmp | ||
|
||
tmp.defs["VERSION"] = """/* Version number of package */ | ||
#undef VERSION""" | ||
|
||
tmp.defs["HAVE_DLFCN_H"] = """/* Define to 1 if you have the <dlfcn.h> header file. */ | ||
#undef HAVE_DLFCN_H""" | ||
|
||
if args.autoheader != None: | ||
with open (args.autoheader, 'w') as f: | ||
for define in tmp.defs.keys (): | ||
if define == "MONO_CORLIB_VERSION" or define == "VERSION" or define == "MONO_ARCHITECTURE" or define == "DISABLED_FEATURES" or define.startswith ("SIZEOF_") or define.startswith ("TARGET_SIZEOF_") or define.startswith ("TARGET_BYTE_ORDER"): | ||
f.write (tmp.defs [define].replace ("#undef " + define, "#define " + define + " @" + define + "@")) | ||
elif False and define.startswith ("ENABLE_"): | ||
f.write (tmp.defs [define].replace ('#undef', '#cmakedefine01')) | ||
else: | ||
f.write (tmp.defs [define].replace ('#undef ' + define, '#cmakedefine ' + define + ' 1')) | ||
f.write ('\n\n') | ||
|
||
emitted_defines = {} | ||
|
||
if args.emit_cmake != None: | ||
with open (args.emit_cmake, 'w') as f: | ||
for value in tmp.headers.keys (): | ||
for header in value.split (" "): | ||
header = header.strip () | ||
if header == "": | ||
continue | ||
define = "HAVE_" + header.replace ("/", "_").replace (".", "_").replace ("-", "_").upper () | ||
emitted_defines [define] = 1 | ||
if used_defines != None and not define in used_defines: | ||
continue | ||
f.write ("check_include_file (\"" + header + "\" " + define + ")\n") | ||
|
||
for value in tmp.funcs.keys (): | ||
for func in value.split (" "): | ||
func = func.strip () | ||
if func == "": | ||
continue | ||
define = "HAVE_" + func.replace ("/", "_").replace (".", "_").replace ("-", "_").upper () | ||
emitted_defines [define] = 1 | ||
if used_defines != None and not define in used_defines: | ||
continue | ||
f.write ("check_function_exists (\"" + func + "\" " + define + ")\n") | ||
for pindex in range(2): | ||
if pindex == 0: | ||
f.write ("### Configure defines\n") | ||
else: | ||
f.write ("### User defines\n") | ||
for define in tmp.defs.keys (): | ||
if define in emitted_defines: | ||
continue | ||
if define.startswith ("HAVE_") and used_defines != None and not define in used_defines: | ||
continue | ||
val = tmp.defs [define] | ||
is_def = "Define to 1 if" in val | ||
if (pindex == 0 and is_def) or (pindex == 1 and not is_def): | ||
f.write ("option (" + define + " \"" + tmp.defs [define].split (" */")[0].replace ("/*", "").replace ("\"", "").strip () + "\")\n") | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/usr/bin/env python3 | ||
import sys | ||
import re | ||
|
||
defines={} | ||
for filename in sys.argv[1:]: | ||
with open (filename, 'r') as f: | ||
for line in f: | ||
line = line.strip () | ||
if '#ifdef' in line or '#ifndef' in line or '#elif' in line or '#if' in line: | ||
line = line.replace ('defined ', 'defined').replace ('\t', ' ') | ||
parts = line.split (' ') | ||
if '#ifdef' in line or '#ifndef' in line: | ||
defines [parts [1]] = 1 | ||
else: | ||
for part in parts[1:]: | ||
match = re.search ('defined\(([a-zA-Z0-9_]+)\)', part) | ||
if match != None: | ||
define = match.group (1) | ||
defines [define] = 1 | ||
else: | ||
match = re.search ('[a-zA-Z_][a-zA-Z0-9_]+', part) | ||
if match != None: | ||
define = match.group (0) | ||
defines [define] = 1 | ||
|
||
for define in defines.keys (): | ||
if define.startswith ("HAVE_"): | ||
print (define) |
Oops, something went wrong.