diff --git a/Help/release/dev/add-apple-swift-language.rst b/Help/release/dev/add-apple-swift-language.rst new file mode 100644 index 000000000..60ce5d82e --- /dev/null +++ b/Help/release/dev/add-apple-swift-language.rst @@ -0,0 +1,9 @@ +add-apple-swift-language +------------------------ + +* CMake learned rudimentary support for the Apple Swift language. When using + the :generator:`Xcode` generator with Xcode 6.1 or higher, one may enable + the ``Swift`` language with the :command:`enable_language` command or the + :command:`project` command (this is an error with other generators or when + Xcode is too old). Then one may list ``.swift`` source files in targets + for compilation. diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake new file mode 100644 index 000000000..bff1ae9cd --- /dev/null +++ b/Modules/CMakeDetermineSwiftCompiler.cmake @@ -0,0 +1,53 @@ + +#============================================================================= +# Copyright 2002-2015 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) + +if("${CMAKE_GENERATOR}" STREQUAL "Xcode") + if(XCODE_VERSION VERSION_LESS 6.1) + message(FATAL_ERROR "Swift language not supported by Xcode ${XCODE_VERSION}") + endif() + set(CMAKE_Swift_COMPILER_XCODE_TYPE sourcecode.swift) + _cmake_find_compiler_path(Swift) +else() + message(FATAL_ERROR "Swift language not supported by \"${CMAKE_GENERATOR}\" generator") +endif() + +# Build a small source file to identify the compiler. +if(NOT CMAKE_Swift_COMPILER_ID_RUN) + set(CMAKE_Swift_COMPILER_ID_RUN 1) + + list(APPEND CMAKE_Swift_COMPILER_ID_MATCH_VENDORS Apple) + set(CMAKE_Swift_COMPILER_ID_MATCH_VENDOR_REGEX_Apple "com.apple.xcode.tools.swift.compiler") + + set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_REGEX "\nCompileSwiftSources[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]* -c[^\r\n]*CompilerIdSwift/CompilerId/main.swift") + set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_INDEX 2) + + # Try to identify the compiler. + set(CMAKE_Swift_COMPILER_ID) + include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) + CMAKE_DETERMINE_COMPILER_ID(Swift "" CompilerId/main.swift) +endif() + +if (NOT _CMAKE_TOOLCHAIN_LOCATION) + get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_Swift_COMPILER}" PATH) +endif () + +include(CMakeFindBinUtils) + +# configure variables set in this file for fast reload later on +configure_file(${CMAKE_ROOT}/Modules/CMakeSwiftCompiler.cmake.in + ${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake + @ONLY + ) diff --git a/Modules/CMakeSwiftCompiler.cmake.in b/Modules/CMakeSwiftCompiler.cmake.in new file mode 100644 index 000000000..45f0a3105 --- /dev/null +++ b/Modules/CMakeSwiftCompiler.cmake.in @@ -0,0 +1,5 @@ +set(CMAKE_Swift_COMPILER "@CMAKE_Swift_COMPILER@") +set(CMAKE_Swift_COMPILER_ID "@CMAKE_Swift_COMPILER_ID@") + +set(CMAKE_Swift_COMPILER_ID_RUN 1) +set(CMAKE_Swift_SOURCE_FILE_EXTENSIONS swift) diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake new file mode 100644 index 000000000..61ad92834 --- /dev/null +++ b/Modules/CMakeSwiftInformation.cmake @@ -0,0 +1,41 @@ + +#============================================================================= +# Copyright 2004-2015 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +set(CMAKE_Swift_OUTPUT_EXTENSION .o) + +# Load compiler-specific information. +if(CMAKE_Swift_COMPILER_ID) + include(Compiler/${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL) +endif() + +# load the system- and compiler specific files +if(CMAKE_Swift_COMPILER_ID) + # load a hardware specific file, mostly useful for embedded compilers + if(CMAKE_SYSTEM_PROCESSOR) + include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) + endif() + include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL) +endif() + +# for most systems a module is the same as a shared library +# so unless the variable CMAKE_MODULE_EXISTS is set just +# copy the values from the LIBRARY variables +if(NOT CMAKE_MODULE_EXISTS) + set(CMAKE_SHARED_MODULE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_Swift_FLAGS}) + set(CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_Swift_FLAGS}) +endif() + +include(CMakeCommonLanguageInclude) + +set(CMAKE_Swift_INFORMATION_LOADED 1) diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake new file mode 100644 index 000000000..918642654 --- /dev/null +++ b/Modules/CMakeTestSwiftCompiler.cmake @@ -0,0 +1,15 @@ + +#============================================================================= +# Copyright 2003-2015 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +set(CMAKE_Swift_COMPILER_WORKS 1) diff --git a/Modules/CompilerId/main.swift.in b/Modules/CompilerId/main.swift.in new file mode 100644 index 000000000..962e85728 --- /dev/null +++ b/Modules/CompilerId/main.swift.in @@ -0,0 +1 @@ +println("CMakeSwiftCompilerId") diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 505929ea7..21075bba5 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -843,6 +843,10 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext, { sourcecode += ".c.objc"; } + else if (ext == "swift") + { + sourcecode += ".swift"; + } else if(ext == "plist") { sourcecode += ".text.plist"; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 886506394..8de1c79d3 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -260,6 +260,12 @@ if(BUILD_TESTING) ADD_TEST_MACRO(MissingSourceFile MissingSourceFile) set_tests_properties(MissingSourceFile PROPERTIES PASS_REGULAR_EXPRESSION "CMake Error at CMakeLists.txt:3 \\(add_executable\\):[ \r\n]*Cannot find source file:[ \r\n]*DoesNotExist/MissingSourceFile.c") + if(CMake_TEST_XCODE_VERSION AND NOT CMake_TEST_XCODE_VERSION VERSION_LESS 6.1) + if(CMAKE_GENERATOR STREQUAL "Xcode") + ADD_TEST_MACRO(SwiftMix SwiftMix) + ADD_TEST_MACRO(SwiftOnly SwiftOnly) + endif() + endif() if(CMAKE_Fortran_COMPILER) ADD_TEST_MACRO(FortranOnly FortranOnly) endif() diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 743ef4be1..c0ac5c826 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -59,6 +59,10 @@ function(add_RunCMake_test_group test types) endforeach() endfunction() +if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 6.1) + set(Swift_ARGS -DXCODE_BELOW_6_1=1) +endif() + if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 3) set(GeneratorToolset_ARGS -DXCODE_BELOW_3=1) endif() @@ -132,6 +136,7 @@ add_RunCMake_test(GNUInstallDirs) add_RunCMake_test(TargetPropertyGeneratorExpressions) add_RunCMake_test(Languages) add_RunCMake_test(ObjectLibrary) +add_RunCMake_test(Swift) add_RunCMake_test(TargetObjects) add_RunCMake_test(TargetSources) add_RunCMake_test(find_dependency) diff --git a/Tests/RunCMake/Swift/CMakeLists.txt b/Tests/RunCMake/Swift/CMakeLists.txt new file mode 100644 index 000000000..74b3ff8de --- /dev/null +++ b/Tests/RunCMake/Swift/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.3) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/Swift/Enable-stdout.txt b/Tests/RunCMake/Swift/Enable-stdout.txt new file mode 100644 index 000000000..39e133fc6 --- /dev/null +++ b/Tests/RunCMake/Swift/Enable-stdout.txt @@ -0,0 +1 @@ +-- The Swift compiler identification is Apple diff --git a/Tests/RunCMake/Swift/Enable.cmake b/Tests/RunCMake/Swift/Enable.cmake new file mode 100644 index 000000000..19f297a87 --- /dev/null +++ b/Tests/RunCMake/Swift/Enable.cmake @@ -0,0 +1 @@ +enable_language(Swift) diff --git a/Tests/RunCMake/Swift/NotSupported-result.txt b/Tests/RunCMake/Swift/NotSupported-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/Swift/NotSupported-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Swift/NotSupported-stderr.txt b/Tests/RunCMake/Swift/NotSupported-stderr.txt new file mode 100644 index 000000000..9a9c23ff3 --- /dev/null +++ b/Tests/RunCMake/Swift/NotSupported-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at .*/Modules/CMakeDetermineSwiftCompiler.cmake:[0-9]+ \(message\): + Swift language not supported by "[^"]*" generator +Call Stack \(most recent call first\): + NotSupported.cmake:[0-9]+ \(enable_language\) + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/Swift/NotSupported.cmake b/Tests/RunCMake/Swift/NotSupported.cmake new file mode 100644 index 000000000..19f297a87 --- /dev/null +++ b/Tests/RunCMake/Swift/NotSupported.cmake @@ -0,0 +1 @@ +enable_language(Swift) diff --git a/Tests/RunCMake/Swift/RunCMakeTest.cmake b/Tests/RunCMake/Swift/RunCMakeTest.cmake new file mode 100644 index 000000000..0a5712142 --- /dev/null +++ b/Tests/RunCMake/Swift/RunCMakeTest.cmake @@ -0,0 +1,11 @@ +include(RunCMake) + +if(RunCMake_GENERATOR STREQUAL Xcode) + if(XCODE_BELOW_6_1) + run_cmake(XcodeTooOld) + else() + run_cmake(Enable) + endif() +else() + run_cmake(NotSupported) +endif() diff --git a/Tests/RunCMake/Swift/XcodeTooOld-result.txt b/Tests/RunCMake/Swift/XcodeTooOld-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/Swift/XcodeTooOld-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt b/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt new file mode 100644 index 000000000..8d18f294f --- /dev/null +++ b/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at .*/Modules/CMakeDetermineSwiftCompiler.cmake:[0-9]+ \(message\): + Swift language not supported by Xcode [0-9.]+ +Call Stack \(most recent call first\): + XcodeTooOld.cmake:[0-9]+ \(enable_language\) + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/Swift/XcodeTooOld.cmake b/Tests/RunCMake/Swift/XcodeTooOld.cmake new file mode 100644 index 000000000..19f297a87 --- /dev/null +++ b/Tests/RunCMake/Swift/XcodeTooOld.cmake @@ -0,0 +1 @@ +enable_language(Swift) diff --git a/Tests/SwiftMix/CMain.c b/Tests/SwiftMix/CMain.c new file mode 100644 index 000000000..13e2f8cc6 --- /dev/null +++ b/Tests/SwiftMix/CMain.c @@ -0,0 +1,4 @@ +extern int ObjCMain(int argc, char const* const argv[]); +int main(int argc, char* argv[]) { + return ObjCMain(argc, argv); +} diff --git a/Tests/SwiftMix/CMakeLists.txt b/Tests/SwiftMix/CMakeLists.txt new file mode 100644 index 000000000..5e50470f6 --- /dev/null +++ b/Tests/SwiftMix/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.3) +project(SwiftMix C Swift) + +add_executable(SwiftMix CMain.c ObjCMain.m SwiftMain.swift ObjC-Swift.h) +set_property(TARGET SwiftMix PROPERTY XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "ObjC-Swift.h") diff --git a/Tests/SwiftMix/ObjC-Swift.h b/Tests/SwiftMix/ObjC-Swift.h new file mode 100644 index 000000000..e69de29bb diff --git a/Tests/SwiftMix/ObjCMain.m b/Tests/SwiftMix/ObjCMain.m new file mode 100644 index 000000000..7fa90aefb --- /dev/null +++ b/Tests/SwiftMix/ObjCMain.m @@ -0,0 +1,4 @@ +#import "SwiftMix-Swift.h" +int ObjCMain(int argc, char const* const argv[]) { + return [SwiftMainClass SwiftMain:argc argv:argv]; +} diff --git a/Tests/SwiftMix/SwiftMain.swift b/Tests/SwiftMix/SwiftMain.swift new file mode 100644 index 000000000..9af988375 --- /dev/null +++ b/Tests/SwiftMix/SwiftMain.swift @@ -0,0 +1,10 @@ +@objc class SwiftMainClass { + class func SwiftMain(argc:Int, argv:UnsafePointer>) -> Int32 { + println("argc: \(argc)") + for (var i = 0; i < argc; ++i) { + var argi = String.fromCString(argv[i]) + println("arg[\(i)]: \(argi)"); + } + return 0; + } +} diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt new file mode 100644 index 000000000..5cb973945 --- /dev/null +++ b/Tests/SwiftOnly/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.3) +project(SwiftOnly Swift) + +add_executable(SwiftOnly main.swift) diff --git a/Tests/SwiftOnly/main.swift b/Tests/SwiftOnly/main.swift new file mode 100644 index 000000000..67be9861e --- /dev/null +++ b/Tests/SwiftOnly/main.swift @@ -0,0 +1 @@ +println("SwiftOnly")