From 8a81f9e1036637e21a47e14fb56bf64133546890 Mon Sep 17 00:00:00 2001 From: James Lyon Date: Sun, 21 Apr 2013 11:20:20 +0100 Subject: [PATCH] Added CMake build system (to facilitate Win64 builds) 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 | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++ config.h.in | 16 +++++++ libtcc.c | 13 ++++-- tccgen.c | 2 +- tests/CMakeLists.txt | 98 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 config.h.in create mode 100644 tests/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..c055ab6a --- /dev/null +++ b/CMakeLists.txt @@ -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 index 00000000..63b8151a --- /dev/null +++ b/config.h.in @@ -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 diff --git a/libtcc.c b/libtcc.c index 9ee4ea69..bf88cc91 100644 --- 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; } diff --git a/tccgen.c b/tccgen.c index 71297be0..d8972960 100644 --- 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 index 00000000..22a35521 --- /dev/null +++ b/tests/CMakeLists.txt @@ -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() -- 2.11.4.GIT