-
Notifications
You must be signed in to change notification settings - Fork 263
build: add CMake based build system for XCTest #214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
|
||
cmake_minimum_required(VERSION 3.4.3) | ||
|
||
list(APPEND CMAKE_MODULE_PATH | ||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") | ||
|
||
project(XCTest | ||
LANGUAGES | ||
C) | ||
|
||
option(XCTEST_PATH_TO_LIBDISPATCH_SOURCE "Path to libdispatch source" "") | ||
option(XCTEST_PATH_TO_LIBDISPATCH_BUILD "Path to libdispatch build" "") | ||
|
||
option(XCTEST_PATH_TO_FOUNDATION_BUILD "Path to Foundation build" "") | ||
|
||
option(XCTEST_PATH_TO_COREFOUNDATION_BUILD "Path to CoreFoundation build" "") | ||
|
||
find_package(LLVM CONFIG) | ||
if(NOT LLVM_FOUND) | ||
message(SEND_ERROR "Could not find LLVM; configure with -DCMAKE_PREFIX_PATH=/path/to/llvm/install") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question for you: my understanding is that there's also a method of configuration in which the To be clear, I'm not asking you to change anything here, this looks right to me, I'm just wondering about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the more modern, CMake way to handle this. LLVM will install a CMake module that can be used. If you use the |
||
endif() | ||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") | ||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") | ||
|
||
include(${LLVM_DIR}/LLVMConfig.cmake) | ||
|
||
list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR}) | ||
include(AddLLVM) | ||
|
||
include(SwiftSupport) | ||
include(GNUInstallDirs) | ||
|
||
set(swift_optimization_flags) | ||
if(CMAKE_BUILD_TYPE MATCHES Release) | ||
set(swift_optimization_flags -O) | ||
endif() | ||
|
||
add_swift_library(XCTest | ||
MODULE_NAME | ||
XCTest | ||
MODULE_LINK_NAME | ||
XCTest | ||
MODULE_PATH | ||
${CMAKE_CURRENT_BINARY_DIR}/swift/XCTest.swiftmodule | ||
OUTPUT | ||
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}XCTest${CMAKE_SHARED_LIBRARY_SUFFIX} | ||
LINK_FLAGS | ||
-L${XCTEST_PATH_TO_LIBDISPATCH_BUILD}/src -ldispatch | ||
-L${XCTEST_PATH_TO_FOUNDATION_BUILD} -lFoundation | ||
SOURCES | ||
Sources/XCTest/Private/WallClockTimeMetric.swift | ||
Sources/XCTest/Private/TestListing.swift | ||
Sources/XCTest/Private/XCTestCaseSuite.swift | ||
Sources/XCTest/Private/TestFiltering.swift | ||
Sources/XCTest/Private/XCTestInternalObservation.swift | ||
Sources/XCTest/Private/ObjectWrapper.swift | ||
Sources/XCTest/Private/PerformanceMeter.swift | ||
Sources/XCTest/Private/PrintObserver.swift | ||
Sources/XCTest/Private/ArgumentParser.swift | ||
Sources/XCTest/Private/XCPredicateExpectation.swift | ||
Sources/XCTest/Public/XCTestRun.swift | ||
Sources/XCTest/Public/XCTestMain.swift | ||
Sources/XCTest/Public/XCTestCase.swift | ||
Sources/XCTest/Public/XCTestSuite.swift | ||
Sources/XCTest/Public/XCTestSuiteRun.swift | ||
Sources/XCTest/Public/XCTestErrors.swift | ||
Sources/XCTest/Public/XCTestObservation.swift | ||
Sources/XCTest/Public/XCTestCaseRun.swift | ||
Sources/XCTest/Public/XCAbstractTest.swift | ||
Sources/XCTest/Public/XCTestObservationCenter.swift | ||
Sources/XCTest/Public/XCTestCase+Performance.swift | ||
Sources/XCTest/Public/XCTAssert.swift | ||
Sources/XCTest/Public/Asynchronous/XCTestCase+NotificationExpectation.swift | ||
Sources/XCTest/Public/Asynchronous/XCTestCase+PredicateExpectation.swift | ||
Sources/XCTest/Public/Asynchronous/XCPredicateExpectationHandler.swift | ||
Sources/XCTest/Public/Asynchronous/XCWaitCompletionHandler.swift | ||
Sources/XCTest/Public/Asynchronous/XCNotificationExpectationHandler.swift | ||
Sources/XCTest/Public/Asynchronous/XCTestCase+Asynchronous.swift | ||
Sources/XCTest/Public/Asynchronous/XCTestExpectation.swift | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I vaguely remembered that globbing source files in CMake was discouraged, so for any other reviewers out there, I looked up the exact reason: https://stackoverflow.com/a/32412044/679254) |
||
SWIFT_FLAGS | ||
${swift_optimization_flags} | ||
|
||
-I${XCTEST_PATH_TO_LIBDISPATCH_SOURCE} | ||
-I${XCTEST_PATH_TO_LIBDISPATCH_BUILD}/src/swift | ||
-Xcc -fblocks | ||
|
||
-I${XCTEST_PATH_TO_FOUNDATION_BUILD}/swift | ||
-Fsystem ${XCTEST_PATH_TO_COREFOUNDATION_BUILD}/System/Library/Frameworks) | ||
|
||
if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) | ||
set(LIT_COMMAND "${PYTHON_EXECUTABLE};${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py" | ||
CACHE STRING "command used to spawn llvm-lit") | ||
else() | ||
find_program(LIT_COMMAND NAMES llvm-lit lit.py lit) | ||
endif() | ||
add_custom_target(check-xctest | ||
COMMAND | ||
${CMAKE_COMMAND} -E env | ||
BUILT_PRODUCTS_DIR=${CMAKE_BINARY_DIR} | ||
CORE_FOUNDATION_BUILT_PRODUCTS_DIR=${XCTEST_PATH_TO_COREFOUNDATION_BUILD} | ||
FOUNDATION_BUILT_PRODUCTS_DIR=${XCTEST_PATH_TO_FOUNDATION_BUILD} | ||
LIBDISPATCH_SRC_DIR=${XCTEST_PATH_TO_LIBDISPATCH_SOURCE} | ||
LIBDISPATCH_BUILD_DIR=${XCTEST_PATH_TO_LIBDISPATCH_BUILD} | ||
LIBDISPATCH_OVERLAY_DIR=${XCTEST_PATH_TO_LIBDISPATCH_BUILD}/swift | ||
SWIFT_EXEC=${CMAKE_SWIFT_COMPILER} | ||
${LIT_COMMAND} -sv ${CMAKE_SOURCE_DIR}/Tests/Functional | ||
COMMENT | ||
"Running XCTest functional test suite" | ||
DEPENDS | ||
XCTest | ||
USES_TERMINAL) | ||
|
||
install(FILES | ||
${CMAKE_CURRENT_BINARY_DIR}/swift/XCTest.swiftdoc | ||
${CMAKE_CURRENT_BINARY_DIR}/swift/XCTest.swiftmodule | ||
DESTINATION | ||
${CMAKE_INSTALL_FULL_LIBDIR}/swift/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}) | ||
install(FILES | ||
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}XCTest${CMAKE_SHARED_LIBRARY_SUFFIX} | ||
DESTINATION | ||
${CMAKE_INSTALL_FULL_LIBDIR}) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
|
||
include(CMakeParseArguments) | ||
|
||
function(add_swift_target target) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like a handy, generic function. Are you anticipating moving it somewhere where all the swift-corelibs-* projects could use it, maybe someday? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. swift-tools-support-core repository is not ready yet but it can be used to hold the shared infrastructure once its open for business! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @modocache - you are right, this is a handy, generic function. I use the same basic functionality in swift-corelibs-libdispatch and am using it in swift-corelibs-foundation too. Once we have the shared repository, moving this would be great. |
||
set(options LIBRARY) | ||
set(single_value_options MODULE_NAME;MODULE_LINK_NAME;MODULE_PATH;MODULE_CACHE_PATH;OUTPUT;TARGET) | ||
set(multiple_value_options CFLAGS;DEPENDS;LINK_FLAGS;SOURCES;SWIFT_FLAGS) | ||
|
||
cmake_parse_arguments(AST "${options}" "${single_value_options}" "${multiple_value_options}" ${ARGN}) | ||
|
||
set(flags ${CMAKE_SWIFT_FLAGS}) | ||
set(link_flags) | ||
|
||
if(AST_TARGET) | ||
list(APPEND flags -target;${AST_TARGET}) | ||
endif() | ||
if(AST_MODULE_NAME) | ||
list(APPEND flags -module-name;${AST_MODULE_NAME}) | ||
else() | ||
list(APPEND flags -module-name;${target}) | ||
endif() | ||
if(AST_MODULE_LINK_NAME) | ||
list(APPEND flags -module-link-name;${AST_MODULE_LINK_NAME}) | ||
endif() | ||
if(AST_MODULE_CACHE_PATH) | ||
list(APPEND flags -module-cache-path;${AST_MODULE_CACHE_PATH}) | ||
endif() | ||
if(AST_SWIFT_FLAGS) | ||
foreach(flag ${AST_SWIFT_FLAGS}) | ||
list(APPEND flags ${flag}) | ||
endforeach() | ||
endif() | ||
if(AST_CFLAGS) | ||
foreach(flag ${AST_CFLAGS}) | ||
list(APPEND flags -Xcc;${flag}) | ||
endforeach() | ||
endif() | ||
if(AST_LINK_FLAGS) | ||
foreach(flag ${AST_LINK_FLAGS}) | ||
list(APPEND link_flags ${flag}) | ||
endforeach() | ||
endif() | ||
if(NOT AST_OUTPUT) | ||
if(AST_LIBRARY) | ||
set(AST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${CMAKE_SHARED_LIBRARY_PREFIX}${target}${CMAKE_SHARED_LIBRARY_SUFFIX}) | ||
else() | ||
set(AST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${target}${CMAKE_EXECUTABLE_SUFFIX}) | ||
endif() | ||
endif() | ||
|
||
set(sources) | ||
foreach(source ${AST_SOURCES}) | ||
get_filename_component(location ${source} PATH) | ||
if(IS_ABSOLUTE ${location}) | ||
list(APPEND sources ${source}) | ||
else() | ||
list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/${source}) | ||
endif() | ||
endforeach() | ||
|
||
set(objs) | ||
set(mods) | ||
set(docs) | ||
set(i 0) | ||
foreach(source ${sources}) | ||
get_filename_component(name ${source} NAME) | ||
|
||
set(obj ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}${CMAKE_C_OUTPUT_EXTENSION}) | ||
set(mod ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}.swiftmodule~partial) | ||
set(doc ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}.swiftdoc~partial) | ||
|
||
set(all_sources ${sources}) | ||
list(INSERT all_sources ${i} -primary-file) | ||
|
||
add_custom_command(OUTPUT | ||
${obj} | ||
${mod} | ||
${doc} | ||
DEPENDS | ||
${source} | ||
COMMAND | ||
${CMAKE_SWIFT_COMPILER} -frontend ${flags} -emit-module-path ${mod} -emit-module-doc-path ${doc} -o ${obj} -c ${all_sources}) | ||
|
||
list(APPEND objs ${obj}) | ||
list(APPEND mods ${mod}) | ||
list(APPEND docs ${doc}) | ||
|
||
math(EXPR i "${i}+1") | ||
endforeach() | ||
|
||
if(AST_LIBRARY) | ||
get_filename_component(module_directory ${AST_MODULE_PATH} DIRECTORY) | ||
|
||
set(module ${AST_MODULE_PATH}) | ||
set(documentation ${module_directory}/${AST_MODULE_NAME}.swiftdoc) | ||
|
||
add_custom_command(OUTPUT | ||
${module} | ||
${documentation} | ||
DEPENDS | ||
${mods} | ||
${docs} | ||
COMMAND | ||
${CMAKE_SWIFT_COMPILER} -frontend ${flags} -sil-merge-partial-modules -emit-module ${mods} -o ${module} -emit-module-doc-path ${documentation}) | ||
endif() | ||
|
||
if(AST_LIBRARY) | ||
set(emit_library -emit-library) | ||
endif() | ||
add_custom_command(OUTPUT | ||
${AST_OUTPUT} | ||
DEPENDS | ||
${objs} | ||
COMMAND | ||
${CMAKE_SWIFT_COMPILER} ${emit_library} ${link_flags} -o ${AST_OUTPUT} ${objs} | ||
COMMAND | ||
${CMAKE_COMMAND} -E copy ${AST_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}) | ||
add_custom_target(${target} | ||
ALL | ||
DEPENDS | ||
${AST_OUTPUT} | ||
${module} | ||
${documentation}) | ||
endfunction() | ||
|
||
function(add_swift_library library) | ||
add_swift_target(${library} LIBRARY ${ARGN}) | ||
endfunction() | ||
|
||
function(add_swift_executable executable) | ||
add_swift_target(${executable} ${ARGN}) | ||
endfunction() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tiny nit-pick/question: is there a reason you're leaving an empty line at the top of the CMake files? Same goes for the
cmake/modules/SwiftSupport.cmake
file below.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, ideally, someone would do the hard work of figuring out how to add the authorship information to the CMake content. I've been lazy and this is something that should be done at some point - it is not for any functional reason, only so that there is uniformity in all the files across the repositories.