Browse Source

MacOS is able to run Hello World!

Zachary Pierson 8 years ago
parent
commit
eeeb90c441
6 changed files with 79 additions and 17 deletions
  1. 1 0
      .gitignore
  2. 16 5
      README.md
  3. 13 4
      build.sh
  4. 11 2
      src/build.c
  5. 6 1
      src/gb/gb.h
  6. 32 5
      src/main.c

+ 1 - 0
.gitignore

@@ -260,3 +260,4 @@ builds
 
 
 # - Linux/MacOS
 # - Linux/MacOS
 odin
 odin
+odin.dSYM

+ 16 - 5
README.md

@@ -22,11 +22,22 @@ The Odin programming language is fast, concise, readable, pragmatic and open sou
 
 
 ## Requirements to build and run
 ## Requirements to build and run
 
 
-* Windows
-* x86-64
-* MSVC 2015 installed (C99 support)
-* Requires MSVC's link.exe as the linker
-	- run `vcvarsall.bat` to setup the path
+- Windows
+	* x86-64
+	* MSVC 2015 installed (C99 support)
+	* LLVM installed
+	* Requires MSVC's link.exe as the linker
+		* run `vcvarsall.bat` to setup the path
+
+- MacOS
+	* x86-64
+	* LLVM explicitly installed (`brew install llvm`)
+	* XCode installed (for the linker)
+
+- GNU/Linux
+	* x86-64
+	* Build tools (ld)
+	* LLVM installed
 
 
 ## Warnings
 ## Warnings
 
 

+ 13 - 4
build.sh

@@ -2,12 +2,21 @@
 
 
 release_mode=0
 release_mode=0
 
 
-warnings_to_disable="-Wno-attributes -Wno-implicit-function-declaration -Wno-incompatible-pointer-types"
+warnings_to_disable="-Wno-attributes -Wno-implicit-function-declaration -Wno-incompatible-pointer-types -Wno-switch -Wno-pointer-sign"
 libraries="-pthread -ldl -lm"
 libraries="-pthread -ldl -lm"
-other_args=""
+other_args="-x c"
+compiler="gcc"
 
 
 if [ "$release_mode" -eq "0" ]; then
 if [ "$release_mode" -eq "0" ]; then
-	other_args="${other_args} -g -fno-inline-functions -fno-inline-small-functions"
+	other_args="${other_args} -g -fno-inline-functions"
 fi
 fi
+if [[ "$(uname)" == "Darwin" ]]; then
 
 
-gcc src/main.c ${warnings_to_disable} ${libraries} ${other_args} -o odin
+	# Set compiler to clang on MacOS
+	# MacOS provides a symlink to clang called gcc, but it's nice to be explicit here.
+	compiler="clang"
+
+	other_args="${other_args} -liconv"
+fi
+
+${compiler} src/main.c ${warnings_to_disable} ${libraries} ${other_args} -o odin

+ 11 - 2
src/build.c

@@ -314,15 +314,24 @@ void init_build_context(BuildContext *bc) {
 
 
 
 
 
 
-	// The linker flags to set the build architecture are different
+	// NOTE(zangent): The linker flags to set the build architecture are different
 	// across OSs. It doesn't make sense to allocate extra data on the heap
 	// across OSs. It doesn't make sense to allocate extra data on the heap
 	// here, so I just #defined the linker flags to keep things concise.
 	// here, so I just #defined the linker flags to keep things concise.
 	#if defined(GB_SYSTEM_WINDOWS)
 	#if defined(GB_SYSTEM_WINDOWS)
+
 	#define linker_flag_x64 "/machine:x64"
 	#define linker_flag_x64 "/machine:x64"
 	#define linker_flag_x86 "/machine:x86"
 	#define linker_flag_x86 "/machine:x86"
+
 	#elif defined(GB_SYSTEM_OSX)
 	#elif defined(GB_SYSTEM_OSX)
-	#error Run "ld -V" to find out what to build programs as. It may be the same as Linux...?
+
+	// NOTE(zangent): MacOS systems are x64 only, so ld doesn't have
+	// an architecture option. All compilation done on MacOS must be x64.
+	GB_ASSERT(str_eq(bc->ODIN_ARCH, str_lit("amd64")));
+
+	#define linker_flag_x64 ""
+	#define linker_flag_x86 ""
 	#else
 	#else
+	// Linux, but also BSDs and the like.
 	#define linker_flag_x64 "-m elf_x86_64"
 	#define linker_flag_x64 "-m elf_x86_64"
 	#define linker_flag_x86 "-m elf_i386"
 	#define linker_flag_x86 "-m elf_i386"
 	#endif
 	#endif

+ 6 - 1
src/gb/gb.h

@@ -3627,7 +3627,12 @@ gb_inline void *gb_memcopy(void *dest, void const *source, isize n) {
 #if defined(_MSC_VER)
 #if defined(_MSC_VER)
 	// TODO(bill): Is this good enough?
 	// TODO(bill): Is this good enough?
 	__movsb(cast(u8 *)dest, cast(u8 *)source, n);
 	__movsb(cast(u8 *)dest, cast(u8 *)source, n);
+#elif defined(GB_SYSTEM_OSX)
+	// NOTE(zangent): I assume there's a reason this isn't being used elsewhere,
+	//  but I don't see it and I can't seem to get this working any other way.
+	memcpy(dest, source, n);
 #elif defined(GB_CPU_X86)
 #elif defined(GB_CPU_X86)
+
 	__asm__ __volatile__("rep movsb" : "+D"(cast(u8 *)dest), "+S"(cast(u8 *)source), "+c"(n) : : "memory");
 	__asm__ __volatile__("rep movsb" : "+D"(cast(u8 *)dest), "+S"(cast(u8 *)source), "+c"(n) : : "memory");
 #else
 #else
 	u8 *d = cast(u8 *)dest;
 	u8 *d = cast(u8 *)dest;
@@ -4964,7 +4969,7 @@ void gb_affinity_destroy(gbAffinity *a) {
 b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) {
 b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) {
 	isize index;
 	isize index;
 	thread_t thread;
 	thread_t thread;
-	GB_ASSERT(thread < gb_affinity_thread_count
+	GB_ASSERT(thread < a->thread_count);
 	thread_affinity_policy_data_t info;
 	thread_affinity_policy_data_t info;
 	kern_return_t result;
 	kern_return_t result;
 
 

+ 32 - 5
src/main.c

@@ -255,6 +255,8 @@ int main(int argc, char **argv) {
 	optimization_level = gb_clamp(optimization_level, 0, 3);
 	optimization_level = gb_clamp(optimization_level, 0, 3);
 
 
 	i32 exit_code = 0;
 	i32 exit_code = 0;
+
+	#if defined(GB_SYSTEM_WINDOWS)
 	// For more passes arguments: http://llvm.org/docs/Passes.html
 	// For more passes arguments: http://llvm.org/docs/Passes.html
 	exit_code = system_exec_command_line_app("llvm-opt", false,
 	exit_code = system_exec_command_line_app("llvm-opt", false,
 		"\"%.*sbin/opt\" \"%s\" -o \"%.*s\".bc "
 		"\"%.*sbin/opt\" \"%s\" -o \"%.*s\".bc "
@@ -270,6 +272,23 @@ int main(int argc, char **argv) {
 	if (exit_code != 0) {
 	if (exit_code != 0) {
 		return exit_code;
 		return exit_code;
 	}
 	}
+	#else
+	// NOTE(zangent): This is separate because it seems that LLVM tools are packaged
+	//   with the Windows version, while they will be system-provided on MacOS and GNU/Linux
+	exit_code = system_exec_command_line_app("llvm-opt", false,
+		"opt \"%s\" -o \"%.*s\".bc "
+		"-mem2reg "
+		"-memcpyopt "
+		"-die "
+		// "-dse "
+		// "-dce "
+		// "-S "
+		"",
+		output_name, LIT(output));
+	if (exit_code != 0) {
+		return exit_code;
+	}
+	#endif
 
 
 	#if defined(GB_SYSTEM_WINDOWS)
 	#if defined(GB_SYSTEM_WINDOWS)
 	timings_start_section(&timings, str_lit("llvm-llc"));
 	timings_start_section(&timings, str_lit("llvm-llc"));
@@ -332,7 +351,7 @@ int main(int argc, char **argv) {
 
 
 	#else
 	#else
 
 
-	// NOTE: Linux / Unix is unfinished and not tested very well.
+	// NOTE(zangent): Linux / Unix is unfinished and not tested very well.
 
 
 
 
 	timings_start_section(&timings, str_lit("llvm-llc"));
 	timings_start_section(&timings, str_lit("llvm-llc"));
@@ -364,7 +383,7 @@ int main(int argc, char **argv) {
 
 
 	// Unlike the Win32 linker code, the output_ext includes the dot, because
 	// Unlike the Win32 linker code, the output_ext includes the dot, because
 	// typically executable files on *NIX systems don't have extensions.
 	// typically executable files on *NIX systems don't have extensions.
-	char *output_ext = "";
+	char *output_ext = ".bin";
 	char *link_settings = "";
 	char *link_settings = "";
 	if (build_context.is_dll) {
 	if (build_context.is_dll) {
 		// Shared libraries are .dylib on MacOS and .so on Linux.
 		// Shared libraries are .dylib on MacOS and .so on Linux.
@@ -380,12 +399,20 @@ int main(int argc, char **argv) {
 		link_settings = "";
 		link_settings = "";
 	}
 	}
 
 
-	exit_code = system_exec_command_line_app("msvc-link", true,
-		"ld \"%.*s\".obj -o \"%.*s.%s\" %s "
+	// TODO(zangent): I'm not sure what to do with lib_str.
+	//   I'll have to look at the format that the libraries are listed to determine what to do.
+	lib_str = "";
+
+	exit_code = system_exec_command_line_app("ld-link", true,
+		"ld \"%.*s\".o -o \"%.*s%s\" %s "
 		"-lc "
 		"-lc "
 		" %.*s "
 		" %.*s "
 		" %s "
 		" %s "
-		"",
+		#if defined(GB_SYSTEM_OSX)
+			// This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit.
+			" -macosx_version_min 10.8.0 "
+		#endif
+		" -e _main ",
 		LIT(output), LIT(output), output_ext,
 		LIT(output), LIT(output), output_ext,
 		lib_str, LIT(build_context.link_flags),
 		lib_str, LIT(build_context.link_flags),
 		link_settings
 		link_settings