Skip to content

Commit

Permalink
Support cross-compiling for windows using cmake
Browse files Browse the repository at this point in the history
When building with TCC, it needs to be a cross-compiler, and
present as ${CMAKE_CURRENT_BINARY_DIR}/cross-tcc

To compile for 64-bit windows:
$mkdir build
$cd build
$cmake ../make -DR3_OS_ID=0.3.40 -DCMAKE_TOOLCHAIN_FILE=../make/Toolchain-cross-mingw64-linux.cmake
  • Loading branch information
zsx committed Sep 14, 2016
1 parent 51ce6f0 commit d24d32d
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 29 deletions.
66 changes: 45 additions & 21 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,50 @@ matrix:
env: OS_ID=0.4.40 BUILD_TYPE=RELEASE R3_CPP=1

# Windows x86, release
#- OS_ID=0.3.1 REL=1 TOOLS=i686-w64-mingw32-
- os: linux
sudo: required
dist: trusty
env: OS_ID=0.3.1 EXE_SUFFIX=.exe BUILD_TYPE=RELEASE R3_CPP=0 EXTRA_CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=Toolchain-cross-mingw32-linux.cmake"
# Windows x86, debug
- os: linux
sudo: required
dist: trusty
env: OS_ID=0.3.1 EXE_SUFFIX=.exe BUILD_TYPE=DEBUG R3_CPP=0 EXTRA_CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=Toolchain-cross-mingw32-linux.cmake"
# Windows x64, release
#- OS_ID=0.3.40 REL=1 TOOLS=x86_64-w64-mingw32-
- os: linux
sudo: required
dist: trusty
env: OS_ID=0.3.40 EXE_SUFFIX=.exe BUILD_TYPE=RELEASE R3_CPP=0 EXTRA_CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=Toolchain-cross-mingw64-linux.cmake"
# Windows x64, debug
- os: linux
sudo: required
dist: trusty
env: OS_ID=0.3.40 EXE_SUFFIX=.exe BUILD_TYPE=DEBUG R3_CPP=0 EXTRA_CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=Toolchain-cross-mingw64-linux.cmake"
# OSX x86
- os: osx
osx_image: xcode7.2
osx_image: xcode8
env: OS_ID=0.2.5 BUILD_TYPE=RELEASE R3_CPP=0
- os: osx
osx_image: xcode7.2
osx_image: xcode8
env: OS_ID=0.2.5 BUILD_TYPE=RELEASE R3_CPP=1
- os: osx
osx_image: xcode7.2
osx_image: xcode8
env: OS_ID=0.2.5 BUILD_TYPE=DEBUG R3_CPP=0
- os: osx
osx_image: xcode8
env: OS_ID=0.2.5 BUILD_TYPE=DEBUG R3_CPP=1
# OSX x64
- os: osx
osx_image: xcode8
env: OS_ID=0.2.40 BUILD_TYPE=RELEASE R3_CPP=0
- os: osx
osx_image: xcode8
env: OS_ID=0.2.40 BUILD_TYPE=RELEASE R3_CPP=1
- os: osx
osx_image: xcode8
env: OS_ID=0.2.40 BUILD_TYPE=DEBUG R3_CPP=0
- os: osx
osx_image: xcode7.2
osx_image: xcode8
env: OS_ID=0.2.40 BUILD_TYPE=DEBUG R3_CPP=1

addons:
Expand All @@ -81,10 +111,6 @@ addons:
- g++-mingw-w64-x86-64
- mingw-w64

before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cmake; fi

install:
# Fetch a Rebol bootstrap binary, which is needed for building Rebol.
#- wget http://www.rebol.com/r3/downloads/r3-a111-4-2.tar.gz
Expand All @@ -95,15 +121,10 @@ install:

script:
- cd make/
# If REL is defined and not empty, we do a release build by compiling with
# NDEBUG defined. (`${parameter+alt_value}` is a Bash-ism documented as:
# "if parameter set, use alt_value, else use null string.")
#- export CC="${TOOLS}${CC}${REL+ -DNDEBUG}"
# We have to set REBOL_TOOL explicitly to circumvent the automatic r3-make
# filename inference, as we always use a Linux r3-make, even when
# cross-compiling to Windows.
#- make -f makefile.boot REBOL_TOOL=r3-make OS_ID="${OS_ID}" CC="${CC}"
- cmake -DR3_OS_ID="${OS_ID}" -DR3_EXTERNAL_FFI=0 -DR3_CPP="${R3_CPP}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" -DR3_WITH_TCC=1 -G "Unix Makefiles"
#compile tcc as a cross-compiler
- if [ "${OS_ID}" = "0.3.1" ]; then mkdir tcc-build && cd tcc-build && cmake -DTCC_BUILD_WIN32=1 -G "Unix Makefiles" ../../external/tcc && make i386-w64-mingw32-tcc i386-w64-mingw32-libtcc1 VERBOSE=1 && cp i386-w64-mingw32-tcc ../cross-tcc && cp i386-w64-mingw32-libtcc1.a ../cross-libtcc1.a && cd .. && rm -fr tcc-build; fi
- if [ "${OS_ID}" = "0.3.40" ]; then mkdir tcc-build && cd tcc-build && cmake -DTCC_BUILD_WIN64=1 -G "Unix Makefiles" ../../external/tcc && make x86_64-w64-mingw32-tcc x86_64-w64-mingw32-libtcc1 VERBOSE=1 && cp x86_64-w64-mingw32-tcc ../cross-tcc && cp x86_64-w64-mingw32-libtcc1.a ../cross-libtcc1.a && cd .. && rm -fr tcc-build; fi
- cmake -DR3_OS_ID="${OS_ID}" -DR3_EXTERNAL_FFI=0 -DR3_CPP="${R3_CPP}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" -DR3_WITH_TCC=1 -G "Unix Makefiles" "${EXTRA_CMAKE_ARGS}"
- make r3-core VERBOSE=1
# A minimal sanity check that the built R3 does _something_. Eventually, we
# should run the full test suite.
Expand All @@ -114,15 +135,18 @@ script:
# Run a second time with piped output to return success/faiure to Travis
- if [ "${OS_ID}" = "0.4.40" ]; then ./r3-core --do 'print {OK}' | grep OK; fi

# overwriting libtcc1.a with the cross-compiled version
- if [ "${OS_ID}" = "0.3.1" -o "${OS_ID}" = "0.3.40" ]; then cp cross-libtcc1.a tcc/libtcc1.a; fi

# Rename files before uploading
- zip r3-core-${TRAVIS_COMMIT}-${OS_ID}-${BUILD_TYPE}-CPP${R3_CPP}.zip r3-core tcc/libtcc1.a
- zip r3-core-${OS_ID}-${TRAVIS_COMMIT}-${BUILD_TYPE}-CPP${R3_CPP}.zip r3-core${EXE_SUFFIX} tcc/libtcc1.a

deploy:
provider: releases
api_key:
secure: V6a5VzBv+ut3hKZKMmnuY4Urzc4QA/EBcfarve837q+7p9QgDseiuW93yUVys7LacIl8D6y13m71QBxzG6LC9WnttNgfy+PfyrMbWfaMvg9zLQQ1jTGKWjW6Fn4/xyU0NYyrjvgxW2itQ4/r9r0lcmKHbsAcm/ZhvLzg4o3dnc0=
file:
- r3-core-${TRAVIS_COMMIT}-${OS_ID}-${BUILD_TYPE}-CPP${R3_CPP}.zip
- r3-core-${OS_ID}-${TRAVIS_COMMIT}-${BUILD_TYPE}-CPP${R3_CPP}.zip
skip_cleanup: true #or, Travis CI deletes all the files created during the build
on:
tags: true
2 changes: 1 addition & 1 deletion external/libffi
Submodule libffi updated from d6aad9 to 0a2287
23 changes: 16 additions & 7 deletions make/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ if (R3_WITH_TCC)
elseif ("${build_type}" STREQUAL "release")
set(tcc_c_flags "${CMAKE_C_FLAGS_RELEASE}")
else ()
message ("ERROR!!!!!!!!!!!!${build_type}!!!")
message (FATAL_ERROR "Unknown CMAKE_BUILD_TYPE: ${build_type}")
endif ()

#flags needs to be a list
Expand All @@ -603,12 +603,22 @@ if (R3_WITH_TCC)

set (SYS_CORE_PREP ${TOP_GENERATED_SRC_DIR}/include/sys-core.i)
set (SYS_CORE_HEADER ${TOP_SRC_DIR}/include/sys-core.h)
get_target_property(TCC_EXE tcc LOCATION)
#set (TCC_EXE ${CMAKE_CURRENT_BINARY_DIR}/tcc/tcc${CMAKE_EXECUTABLE_SUFFIX})

set (TCC_DEPENDS "libtcc")
message("HOST: ${CMAKE_HOST_SYSTEM} SYSTEM: ${CMAKE_SYSTEM}")
if ("${CMAKE_HOST_SYSTEM}" STREQUAL "${CMAKE_SYSTEM}") #native build
get_target_property(TCC_EXE tcc LOCATION)
list(APPEND TCC_DEPENDS "tcc;libtcc1")
else () #cross-compile
set(TCC_EXE ${CMAKE_CURRENT_BINARY_DIR}/cross-tcc)
if (NOT EXISTS ${TCC_EXE})
message (FATAL_ERROR "Can't find tcc at: ${TCC_EXE}")
endif ()
endif ()

if (WIN32)
list(APPEND tcc_c_flag_list "-I${TCC_DIR}/win32/include")
list(APPEND tcc_c_flag_list "-DPVAR=TVAR -DTVAR=\"extern __attribute__((dllimport))\"")
list(APPEND tcc_c_flag_list "-DPVAR=TVAR;-DTVAR=extern __attribute__((dllimport))")
endif ()

list(APPEND tcc_c_flag_list "-DREN_C_STDIO_OK") #allow stdio.h
Expand All @@ -618,14 +628,13 @@ if (R3_WITH_TCC)
${SYS_CORE_PREP}
COMMAND ${TCC_EXE} -E -dD -o ${SYS_CORE_PREP} ${SYS_CORE_HEADER} -I${TCC_DIR}/include -I${TOP_GENERATED_SRC_DIR}/include -I${TOP_SRC_DIR}/include -I${TOP_SRC_DIR}/codecs ${TCC_ARGS} ${tcc_c_flag_list}
DEPENDS
tcc
libtcc1
${TCC_DEPENDS}
${TOOLS_DIR}/make-embedded-header.r
${CMAKE_CURRENT_BINARY_DIR}/tcc/tcc
${BOOT_OUTPUT}
${HEADER_OUTPUT}
${SYS_CORE_HEADER}
${TOP_GENERATED_SRC_DIR}/include/host-lib.h
VERBATIM
)

add_custom_command(OUTPUT
Expand Down
29 changes: 29 additions & 0 deletions make/Toolchain-cross-mingw32-linux.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_PROCESSOR "X86")

# Choose an appropriate compiler prefix

# for classical mingw32
# see http://www.mingw.org/
#set(COMPILER_PREFIX "i586-mingw32msvc")

# for 32 or 64 bits mingw-w64
# see http://mingw-w64.sourceforge.net/
set(COMPILER_PREFIX "i686-w64-mingw32")

# which compilers to use for C and C++
find_program(CMAKE_RC_COMPILER NAMES ${COMPILER_PREFIX}-windres)
find_program(CMAKE_C_COMPILER NAMES ${COMPILER_PREFIX}-gcc)
find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++)


# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH /usr/${COMPILER_PREFIX} ${USER_ROOT_PATH})

# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
27 changes: 27 additions & 0 deletions make/Toolchain-cross-mingw64-linux.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_PROCESSOR "x86_64")

# Choose an appropriate compiler prefix

# for classical mingw32
# see http://www.mingw.org/
#set(COMPILER_PREFIX "i586-mingw32msvc")

# for 32 or 64 bits mingw-w64
# see http://mingw-w64.sourceforge.net/
set(COMPILER_PREFIX "x86_64-w64-mingw32")

# which compilers to use for C and C++
find_program(CMAKE_RC_COMPILER NAMES ${COMPILER_PREFIX}-windres)
find_program(CMAKE_C_COMPILER NAMES ${COMPILER_PREFIX}-gcc)
find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++)

SET(CMAKE_FIND_ROOT_PATH /usr/${COMPILER_PREFIX} ${USER_ROOT_PATH})

# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

0 comments on commit d24d32d

Please sign in to comment.