🔥 Target
강의 목차
Target
클래스는 Swift 패키지를 구성하는 기본 단위입니다. 각 타깃은 모듈이나 테스트로 컴파일되는 소스 파일들을 담고 있죠. 타깃을 다른 패키지에서 쓸 수 있게 하려면 타깃을 포함한 제품을 만들면 돼요. 타깃은 같은 패키지 안의 다른 타깃이나 패키지가 의존하는 제품에 의존할 수 있어요.
메서드
static func target(...) -> Target
이 메서드는 일반 타깃을 만들어 줍니다. 타깃은 Swift나 C 계열 소스 파일 중 하나만 가질 수 있어요. 라이브러리나 실행 파일에 들어갈 수 있는 일반 모듈로 빌드되는 코드를 담고 있지만, 실행 파일의 메인 타깃으로는 쓸 수 없어요.
이렇게 일반 타깃을 정의할 수 있죠:
let myTarget = Target.target( name: "MyTarget", dependencies: [ .target(name: "AnotherTarget"), .product(name: "SomeProduct", package: "SomePackage") ], path: "Sources/MyTarget", exclude: ["Sources/MyTarget/ExcludedFile.swift"], sources: ["Sources/MyTarget/Source1.swift", "Sources/MyTarget/Source2.swift"], publicHeadersPath: "Sources/MyTarget/include", cSettings: [ .define("MACRO_NAME", to: "value") ] )
swift
name
: 타깃 이름이에요.dependencies
: 타깃이 의존하는 것들이에요. 패키지 안의 다른 타깃이나 패키지 의존성의 제품이 될 수 있죠.path
: 타깃의 경로예요. 보통 Swift 패지지 매니저는 정해진 경로에서 타깃 소스를 찾아요. 패키지 루트 밖의 경로는 쓸 수 없어요.exclude
: 소스나 리소스 파일로 취급하지 말아야 할 파일이나 폴더 경로예요. 타깃 폴더 기준으로 상대 경로로 쓰면 돼요.sources
보다 우선순위가 높아요.sources
: 소스 파일 목록이에요. 폴더 경로를 주면 Swift 패지지 매니저가 재귀적으로 유효한 소스 파일을 찾아요.publicHeadersPath
: C 계열 라이브러리 타깃의 공용 헤더 폴더예요.cSettings
: 이 타깃의 C 설정이에요.
static func executableTarget(...) -> Target
이 메서드는 실행 파일 타깃을 만들어 줍니다. 실행 파일 타깃은 Swift나 C 계열 소스 파일 중 하나만 가질 수 있어요. 실행 파일의 메인 타깃으로 쓸 수 있는 실행 파일 모듈로 빌드되는 코드를 담고 있죠. 타깃에는 main.swift
, main.m
, main.c
, main.cpp
중 하나의 소스 파일이나 @main
키워드가 있는 소스 파일이 있어야 해요.
이렇게 실행 파일 타깃을 정의할 수 있어요:
let myExecutableTarget = Target.executableTarget( name: "MyExecutable", dependencies: [ .target(name: "MyLibrary") ], path: "Sources/MyExecutable", exclude: ["Sources/MyExecutable/ExcludedFile.swift"], sources: ["Sources/MyExecutable/main.swift"], swiftSettings: [ .unsafeFlags(["-cross-module-optimization"], .when(configuration: .release)) ] )
swift
name
: 타깃 이름이에요.dependencies
: 타깃이 의존하는 것들이에요. 패키지 안의 다른 타깃이나 패키지 의존성의 제품이 될 수 있죠.path
: 타깃의 경로예요. 보통 Swift 패지지 매니저는 정해진 경로에서 타깃 소스를 찾아요. 패키지 루트 밖의 경로는 쓸 수 없어요.exclude
: 소스나 리소스 파일로 취급하지 말아야 할 파일이나 폴더 경로예요. 타깃 폴더 기준으로 상대 경로로 쓰면 돼요.sources
보다 우선순위가 높아요.sources
: 소스 파일 목록이에요. 폴더 경로를 주면 Swift 패지지 매니저가 재귀적으로 유효한 소스 파일을 찾아요.swiftSettings
: 이 타깃의 Swift 설정이에요.
static func testTarget(...) -> Target
이 메서드는 테스트 타깃을 만들어 줍니다. XCTest 테스트를 쓰면 돼요. 테스트 타깃은 보통 테스트할 타깃에 의존성을 갖죠.
이렇게 테스트 타깃을 정의할 수 있어요:
let myTestTarget = Target.testTarget( name: "MyTests", dependencies: [ .target(name: "MyLibrary") ], path: "Tests/MyTests", exclude: ["Tests/MyTests/ExcludedTest.swift"], sources: ["Tests/MyTests/Test1.swift", "Tests/MyTests/Test2.swift"], cxxSettings: [ .headerSearchPath("Tests/MyTests/Headers") ] )
swift
name
: 타깃 이름이에요.dependencies
: 타깃이 의존하는 것들이에요. 패키지 안의 다른 타깃이나 패키지 의존성의 제품이 될 수 있죠.path
: 타깃의 경로예요. 보통 Swift 패지지 매니저는 정해진 경로에서 타깃 소스를 찾아요. 패키지 루트 밖의 경로는 쓸 수 없어요.exclude
: 소스나 리소스 파일로 취급하지 말아야 할 파일이나 폴더 경로예요. 타깃 폴더 기준으로 상대 경로로 쓰면 돼요.sources
보다 우선순위가 높아요.sources
: 소스 파일 목록이에요. 폴더 경로를 주면 Swift 패지지 매니저가 재귀적으로 유효한 소스 파일을 찾아요.cxxSettings
: 이 타깃의 C++ 설정이에요.
static func systemLibrary(...) -> Target
이 메서드는 시스템 라이브러리 타깃을 만들어 줍니다. 시스템에 설치된 라이브러리를 Swift 패키지에서 쓸 수 있게 해주죠. 이런 라이브러리는 보통 Homebrew나 apt-get 같은 시스템 패지지 매니저로 설치되고, modulemap
파일이나 pkgConfig
이름 같은 메타데이터로 Swift 패키지에 알려져요.
이렇게 시스템 라이브러리 타깃을 정의할 수 있어요:
let mySystemLibrary = Target.systemLibrary( name: "MySystemLibrary", path: "Sources/MySystemLibrary", pkgConfig: "my-system-library", providers: [ .brew(["my-system-library"]), .apt(["my-system-library-dev"]) ] )
swift
name
: 타깃 이름이에요.path
: 타깃의 경로예요. 보통 Swift 패지지 매니저는 정해진 경로에서 타깃 소스를 찾아요. 패키지 루트 밖의 경로는 쓸 수 없어요.pkgConfig
: 이 시스템 라이브러리의pkg-config
파일 이름이에요.providers
: 이 시스템 라이브러리의 제공자예요. Homebrew, apt 등의 시스템 패지지 매니저가 될 수 있죠.
static func binaryTarget(name:url:checksum:) -> Target
이 메서드는 원격 아티팩트를 참조하는 바이너리 타깃을 만들어 줍니다. 바이너리 타깃은 미리 빌드된 바이너리 아티팩트의 URL을 제공해요. 지금은 Apple 플랫폼용 아티팩트만 지원해요.
이렇게 원격 URL로 바이너리 타깃을 정의할 수 있어요:
let myBinaryTarget = Target.binaryTarget( name: "MyBinaryLib", url: "<https://example.com/mybinarylib.zip>", checksum: "1a2b3c4d5e6f7g8h9i0j" )
swift
name
: 타깃 이름이에요.url
: 바이너리 아티팩트의 URL이에요. 이 URL은 루트 폴더에 바이너리 아티팩트가 들어 있는 압축 파일을 가리켜야 해요.checksum
: 바이너리 아티팩트가 들어 있는 압축 파일의 체크섬이에요.
바이너리 타깃은 Apple 플랫폼에서만 쓸 수 있어요.
static func binaryTarget(name:path:) -> Target
이 메서드는 디스크에 있는 아티팩트를 참조하는 바이너리 타깃을 만들어 줍니다. 바이너리 타깃은 미리 빌드된 바이너리 아티팩트의 경로를 제공해요. Swift 패지지 매니저는 Apple 플랫폼용 바이너리 타깃만 지원해요.
이렇게 로컬 경로로 바이너리 타깃을 정의할 수 있어요:
let myBinaryTarget = Target.binaryTarget( name: "MyBinaryLib", path: "path/to/mybinarylib.xcframework" )
swift
name
: 타깃 이름이에요.path
: 바이너리 아티팩트의 경로예요. 이 경로는 바이너리 아티팩트를 직접 가리키거나 루트에 바이너리 아티팩트가 들어 있는 압축 파일을 가리킬 수 있어요.
바이너리 타깃은 Apple 플랫폼에서만 쓸 수 있어요.
이렇게 Target
클래스로 여러 종류의 타깃을 정의할 수 있죠. 일반 타깃, 실행 파일 타깃, 테스트 타깃, 시스템 라이브러리 타깃, 바이너리 타깃 등을 만들 수 있어요. 각 타깃은 고유한 속성과 설정을 가질 수 있고, 패키지 안의 다른 타깃이나 의존성에 의존할 수 있죠.
Target
클래스의 메서드를 잘 활용하면 패키지 구조와 구성 요소를 잘 정의할 수 있어요. 타깃을 잘 설정하면 코드 모듈화, 의존성 관리, 빌드 과정 등을 잘 처리할 수 있죠.
다음은 Target
클래스로 패키지를 구성하는 예시예요:
let package = Package( name: "MyPackage", products: [ .library(name: "MyLibrary", targets: ["MyLibrary"]), .executable(name: "MyExecutable", targets: ["MyExecutable"]) ], dependencies: [ .package(url: "<https://github.com/example/SomeDependency.git>", from: "1.0.0") ], targets: [ .target( name: "MyLibrary", dependencies: [ .product(name: "SomeDependency", package: "SomeDependency") ] ), .executableTarget( name: "MyExecutable", dependencies: ["MyLibrary"] ), .testTarget( name: "MyTests", dependencies: ["MyLibrary"] ) ] )
swift
이 예시는 Package
매니페스트로 MyPackage
라는 패키지를 정의하고 있어요. 이 패키지에는 다음 구성 요소가 있죠:
products
: 패키지에서 만들 라이브러리와 실행 파일을 정의해요.MyLibrary
라는 라이브러리와MyExecutable
이라는 실행 파일이 있네요.dependencies
: 패키지의 외부 의존성을 정의해요. 여기서는SomeDependency
라는 의존성을 GitHub URL과 버전 요구 사항으로 지정하고 있어요.targets
: 패키지의 타깃을 정의해요.MyLibrary
타깃은SomeDependency
제품에 의존하는 일반 타깃이에요.MyExecutable
타깃은MyLibrary
타깃에 의존하는 실행 파일 타깃이죠.MyTests
타깃은MyLibrary
타깃에 의존하는 테스트 타깃이에요.
이렇게 Target
클래스로 패키지의 타깃을 정의하고, 타깃 간의 의존성을 설정할 수 있어요. 이를 통해 코드 구조와 의존성을 명확히 표현하고 관리할 수 있습니다.
Swift 패키지 매니페스트에서 Target
클래스를 활용해 타깃을 정의하는 건 패키지 구성과 빌드 과정을 제어하는 데 정말 중요해요. 타깃을 잘 구성하고 의존성을 잘 설정하면 코드 모듈화, 재사용성, 테스트 가능성 등을 높일 수 있습니다.