Added CMake build system (to facilitate Win64 builds)
authorJames Lyon <jamesly0n@hotmail.com>
Sun, 21 Apr 2013 10:20:20 +0000 (21 11:20 +0100)
committerJames Lyon <jamesly0n@hotmail.com>
Sun, 21 Apr 2013 10:20:20 +0000 (21 11:20 +0100)
Win32 build and tests work under CMake, however I haven't added
install code yet. Win64 build fails due to chkstk.S failing to
assemble.

CMakeLists.txt [new file with mode: 0644]
config.h.in [new file with mode: 0644]
libtcc.c
tccgen.c
tests/CMakeLists.txt [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c055ab6
--- /dev/null
@@ -0,0 +1,129 @@
+project(tcc C)
+cmake_minimum_required(VERSION 2.6)
+enable_testing()
+
+set(CMAKE_USE_RELATIVE_PATHS ON)
+
+if(WIN32)
+  set(BUILD_SHARED_LIBS ON)
+  if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM")
+    set(TCC_TARGET_DEFAULT "WinCE")
+  elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(TCC_TARGET_DEFAULT "Win64")
+  else()
+    set(TCC_TARGET_DEFAULT "Win32")
+  endif()
+else()
+  if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
+    set(TCC_TARGET_DEFAULT "ARM")
+    if(CMAKE_SYSTEM_PROCESSOR MATCHES "^armv5")
+      set(TCC_ARM_VERSION_DEFAULT 5)
+    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^armv6")
+      set(TCC_ARM_VERSION_DEFAULT 6)
+    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^armv7")
+      set(TCC_ARM_VERSION_DEFAULT 7)
+    else()
+      set(TCC_ARM_VERSION_DEFAULT 4)
+    endif()
+  elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(TCC_TARGET_DEFAULT "x86_64")
+  else()
+    set(TCC_TARGET_DEFAULT "i386")
+  endif()
+endif()
+
+set(TCC_TARGET_LIST "Win32" "Win64" "WinCE" "i386" "x86_64" "ARM" "C67")
+set(TCC_TARGET ${TCC_TARGET_DEFAULT} CACHE STRING "Target OS")
+set_property(CACHE TCC_TARGET PROPERTY STRINGS ${TCC_TARGET_LIST})
+
+set(TCC_ARM_VERSION ${TCC_ARM_VERSION_DEFAULT} CACHE STRING "ARM target CPU version")
+set_property(CACHE TCC_ARM_VERSION PROPERTY STRINGS 4 5 6 7)
+set(TCC_ARM_EABI OFF CACHE BOOL "Enable EABI on ARM")
+set(TCC_ARM_VFP OFF CACHE BOOL "Enable VFP on ARM")
+set(TCC_ARM_HARDFLOAT OFF CACHE BOOL "Enable hardware floating point on ARM")
+
+set(I386_SOURCES i386-gen.c i386-asm.c i386-asm.h i386-tok.h)
+set(X86_64_SOURCES x86_64-gen.c i386-asm.c x86_64-asm.h)
+
+if(TCC_TARGET STREQUAL "Win32")
+  set(TCC_TARGET_I386 ON)
+  set(TCC_TARGET_PE ON)
+  set(LIBTCC_TARGET_SOURCES ${I386_SOURCES} tccpe.c)
+elseif(TCC_TARGET STREQUAL "Win64")
+  set(TCC_TARGET_PE ON)
+  set(TCC_TARGET_X86_64 ON)
+  set(LIBTCC_TARGET_SOURCES ${X86_64_SOURCES} tccpe.c)
+elseif(TCC_TARGET STREQUAL "WinCE")
+  set(TCC_TARGET_ARM ON)
+  set(LIBTCC_TARGET_SOURCES arm-gen.c tccpe.c)
+elseif(TCC_TARGET STREQUAL "i386")
+  set(TCC_TARGET_I386 ON)
+  set(LIBTCC_TARGET_SOURCES ${I386_SOURCES})
+elseif(TCC_TARGET STREQUAL "x86-64")
+  set(TCC_TARGET_X86_64 ON)
+  set(LIBTCC_TARGET_SOURCES ${X86_64_SOURCES})
+elseif(TCC_TARGET STREQUAL "ARM")
+  set(TCC_TARGET_ARM ON)
+  set(LIBTCC_TARGET_SOURCES arm-gen.c)
+elseif(TCC_TARGET STREQUAL "C67")
+  set(TCC_TARGET_C67 ON)
+  set(LIBTCC_TARGET_SOURCES c67-gen.c tcccoff.c)
+else()
+  message(FATAL_ERROR "Unrecognised target in TCC_TARGET, must be one of ${TCC_TARGET_LIST}")
+endif()
+
+file(STRINGS "VERSION" TCC_VERSION)
+list(GET TCC_VERSION 0 TCC_VERSION)
+include_directories(${CMAKE_BINARY_DIR})
+configure_file(config.h.in config.h)
+
+add_library(libtcc
+libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
+tcc.h config.h libtcc.h tcctok.h
+${LIBTCC_TARGET_SOURCES}
+)
+set_target_properties(libtcc PROPERTIES PREFIX "")
+
+add_executable(tcc tcc.c)
+target_link_libraries(tcc libtcc)
+set(TCC_CFLAGS -I${CMAKE_SOURCE_DIR}/include)
+if(TCC_TARGET MATCHES "^Win")
+  set(TCC_CFLAGS ${TCC_CFLAGS} -I${CMAKE_SOURCE_DIR}/win32/include)
+endif()
+
+add_executable(tiny_impdef win32/tools/tiny_impdef.c)
+add_executable(tiny_libmaker win32/tools/tiny_libmaker.c)
+
+set(LIBTCC1_I386_SOURCES lib/alloca86.S lib/alloca86-bt.S lib/bcheck.c)
+set(LIBTCC1_WIN_SOURCES win32/lib/crt1.c win32/lib/wincrt1.c win32/lib/dllcrt1.c win32/lib/dllmain.c win32/lib/chkstk.S)
+
+if(TCC_TARGET STREQUAL "Win32")
+  set(LIBTCC1_SOURCES ${LIBTCC1_I386_SOURCES} ${LIBTCC1_WIN_SOURCES})
+elseif(TCC_TARGET STREQUAL "Win64")
+  set(LIBTCC1_SOURCES lib/alloca86_64.S ${LIBTCC1_WIN_SOURCES})
+elseif(TCC_TARGET STREQUAL "i386")
+  set(LIBTCC1_SOURCES ${LIBTCC1_I386_SOURCES})
+elseif(TCC_TARGET STREQUAL "x86-64")
+  set(LIBTCC1_SOURCES lib/alloca86_64.S)
+endif()
+
+if (TCC_TARGET MATCHES "^Win")
+  set(XCC tcc ${TCC_CFLAGS} -B${CMAKE_SOURCE_DIR}/win32)
+  set(XAR tiny_libmaker${CMAKE_EXECUTABLE_SUFFIX})
+  set(XDEPENDS tiny_libmaker)
+endif()
+
+if(LIBTCC1_SOURCES)
+  list(APPEND LIBTCC1_SOURCES lib/libtcc1.c)
+  foreach(LIBTCC1_C ${LIBTCC1_SOURCES})
+    string(REGEX MATCH "[^/]+$" LIBTCC1_O ${LIBTCC1_C})
+    string(REGEX MATCH "^[^.]+" LIBTCC1_O ${LIBTCC1_O})
+    set(LIBTCC1_O ${LIBTCC1_O}.o)
+    add_custom_command(OUTPUT ${LIBTCC1_O} COMMAND ${XCC} -c ${CMAKE_SOURCE_DIR}/${LIBTCC1_C} -o ${LIBTCC1_O})
+    list(APPEND LIBTCC1_OBJECTS ${LIBTCC1_O})
+  endforeach()
+  add_custom_command(OUTPUT libtcc1.a COMMAND ${XAR} libtcc1.a ${LIBTCC1_OBJECTS} DEPENDS ${LIBTCC1_OBJECTS} ${XDEPENDS})
+  add_custom_target(libtcc1 ALL DEPENDS libtcc1.a)
+endif()
+
+add_subdirectory(tests)
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..63b8151
--- /dev/null
@@ -0,0 +1,16 @@
+#define CONFIG_TCCDIR "${CMAKE_INSTALL_PREFIX}"
+#define TCC_VERSION "${TCC_VERSION}"
+
+#cmakedefine CONFIG_WIN32
+#cmakedefine CONFIG_WIN64
+
+#cmakedefine TCC_TARGET_I386
+#cmakedefine TCC_TARGET_X86_64
+#cmakedefine TCC_TARGET_ARM
+#cmakedefine TCC_TARGET_C67
+
+#cmakedefine TCC_TARGET_PE
+#define TCC_ARM_VERSION ${TCC_ARM_VERSION}
+#cmakedefine TCC_ARM_VFP
+#cmakedefine TCC_ARM_EABI
+#cmakedefine TCC_ARM_HARDFLOAT
index 9ee4ea6..bf88cc9 100644 (file)
--- a/libtcc.c
+++ b/libtcc.c
@@ -80,12 +80,19 @@ ST_FUNC void asm_global_instr(void)
 /********************************************************/
 
 #ifdef _WIN32
+// GCC appears to use '/' for relative paths and '\\' for absolute paths on Windows
 static char *normalize_slashes(char *path)
 {
     char *p;
-    for (p = path; *p; ++p)
-        if (*p == '\\')
-            *p = '/';
+    if (path[1] == ':') {
+        for (p = path+2; *p; ++p)
+            if (*p == '/')
+                *p = '\\';
+    } else {
+        for (p = path; *p; ++p)
+            if (*p == '\\')
+                *p = '/';
+    }
     return path;
 }
 
index 71297be..d897296 100644 (file)
--- a/tccgen.c
+++ b/tccgen.c
@@ -3712,7 +3712,7 @@ ST_FUNC void unary(void)
             }
         }
         break;
-#ifdef TCC_TARGET_X86_64
+#if defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_PE)
     case TOK_builtin_va_arg_types:
         {
             CType type;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..22a3552
--- /dev/null
@@ -0,0 +1,98 @@
+include_directories(${CMAKE_SOURCE_DIR})
+
+add_executable(abitest-cc abitest.c)
+target_link_libraries(abitest-cc libtcc)
+add_test(NAME abitest-cc WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND abitest-cc lib_path=${CMAKE_BINARY_DIR} include=${CMAKE_SOURCE_DIR}/include)
+
+set(ABITEST_TCC abitest-tcc${CMAKE_EXECUTABLE_SUFFIX})
+get_property(LIBTCC_LIB TARGET libtcc PROPERTY LOCATION)
+add_custom_command(OUTPUT ${ABITEST_TCC} COMMAND tcc ${TCC_CFLAGS} -I${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/abitest.c ${LIBTCC_LIB} -o ${ABITEST_TCC} DEPENDS abitest.c)
+add_custom_target(abitest-tcc-exe ALL DEPENDS ${ABITEST_TCC})
+
+add_test(NAME abitest-tcc WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${ABITEST_TCC} lib_path=${CMAKE_BINARY_DIR} include=${CMAKE_SOURCE_DIR}/include)
+
+add_executable(tcctest-cc tcctest.c)
+target_link_libraries(tcctest-cc libtcc)
+set_target_properties(tcctest-cc PROPERTIES INCLUDE_DIRECTORIES "${CMAKE_BINARY_DIR};${CMAKE_SOURCE_DIR}/include" COMPILE_FLAGS -std=gnu99)
+
+set(TCC_TEST_CFLAGS ${TCC_CFLAGS} -B${CMAKE_BINARY_DIR} -I${CMAKE_BINARY_DIR})
+if(WIN32)
+  set(TCC_TEST_CFLAGS ${TCC_TEST_CFLAGS} -I${CMAKE_SOURCE_DIR}/win32/include/winapi)
+endif()
+set(TCC_TEST_SOURCE ${TCC_TEST_CFLAGS} -run ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
+set(TCC_TEST_RUN ${TCC_TEST_CFLAGS} -DONE_SOURCE -run ${CMAKE_SOURCE_DIR}/tcc.c)
+
+add_custom_command(OUTPUT tcctest.ref COMMAND tcctest-cc > tcctest.ref)
+add_custom_command(OUTPUT tcctest.1 COMMAND tcc ${TCC_TEST_SOURCE} > tcctest.1)
+add_custom_command(OUTPUT tcctest.2 COMMAND tcc ${TCC_TEST_RUN} ${TCC_TEST_SOURCE} > tcctest.2)
+add_custom_command(OUTPUT tcctest.3 COMMAND tcc ${TCC_TEST_RUN} ${TCC_TEST_RUN} ${TCC_TEST_SOURCE} > tcctest.3)
+add_custom_target(tcctest-ref ALL DEPENDS tcctest.ref tcctest.1 tcctest.2 tcctest.3)
+
+find_program(DIFF diff C:/MinGW/msys/1.0/bin)
+
+add_test(test1 ${DIFF} tcctest.ref tcctest.1)
+add_test(test2 ${DIFF} tcctest.ref tcctest.2)
+add_test(test3 ${DIFF} tcctest.ref tcctest.3)
+
+set(MORETESTS
+ 00_assignment
+ 01_comment
+ 02_printf
+ 03_struct
+ 04_for
+ 05_array
+ 06_case
+ 07_function
+ 08_while
+ 09_do_while
+ 10_pointer
+ 11_precedence
+ 12_hashdefine
+ 13_integer_literals
+ 14_if
+ 15_recursion
+ 16_nesting
+ 17_enum
+ 18_include
+ 19_pointer_arithmetic
+ 20_pointer_comparison
+ 21_char_array
+ 22_floating_point
+ 23_type_coercion
+ 24_math_library
+ 25_quicksort
+ 26_character_constants
+ 27_sizeof
+ 28_strings
+ 29_array_address
+ 31_args
+ 32_led
+ 33_ternary_op
+ 35_sizeof
+ 36_array_initialisers
+ 37_sprintf
+ 38_multiple_array_index
+ 39_typedef
+ 40_stdio
+ 41_hashif
+ 42_function_pointer
+ 43_void_param
+ 44_scoped_declarations
+ 45_empty_for
+ 47_switch_return
+ 48_nested_break
+ 49_bracket_evaluation
+ 50_logical_second_arg
+ 51_static
+ 52_unnamed_enum
+ 54_goto
+ 55_lshift_type
+)
+if(WIN32)
+  list(REMOVE_ITEM MORETESTS 24_math_library)
+  list(REMOVE_ITEM MORETESTS 28_strings)
+endif()
+foreach(testfile ${MORETESTS})
+  add_test(NAME ${testfile} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests2
+           COMMAND tcc ${TCC_CFLAGS} -run ${testfile}.c - arg1 arg2 arg3 arg4 | ${DIFF} - ${testfile}.expect)
+endforeach()