How can I set the swiftc output directory?

I'm developing a server application run on CLI in VSCode with SPM description. The compiler produces (besides 1000 of hopefully temporary files) a single binary executable. Thats good. However I need resources from directories relative to my sources. So I want swiftc to place the generated binary in the root directory of my sources. And start debugging from there as well. Can' figure that out.

In C# I simply do: <OutputPath>/</OutputPath>

I wonder if it’s possible to setup a post compilation step to copy the binary from the build directory into your source directory. For me on Linux if SwiftPM can’t do it I’d use a Makefile or a bash script to do it, then have that file call swift build for me and copy the binary, but I do wonder if there is another way.

1 Like

Most runner environments will have a way of specifying a working directory, which I usually find easier than trying to coerce build systems into doing my will.

Looking at vscode-lldb, it appears the setting in the launch.json configuration is cwd. If you're using launch.json, try adding "cwd": "${workspaceFolder}" to your debug configuration. If you're using some other way of launching, look in the documentation for 'working directory' settings.

Failing that, it doesn't seem like SPM is set up for outputting to specific locations (if I'm missing a swift build flag, someone please correct me!). If you really do have to move the executable, a post-build action like @xtremekforever suggested is probably the way to go.

I have a couple questions before I launch into an answer because I use extra files a lot...

  • confirming you are using the SPM build/run (swift build / swift run in a CLI or the VScode tools not actually opening the command line and typing swiftc ... because that's just swiftc main.swift -o ../location/to/myappname) ?
  • Is your ultimate goal to add this program to your path and have it find similar files in subdirs of the pwd where it is run or really THESE files are what your program will always need
  • are you writing a pure Swift project or combining it with C/C++
  • what about including these files as resources didn't work for you?
    -- Package — Swift Package Manager
    -- Resource | Apple Developer Documentation
  • Are you familiar with using .env files and have you loaded them in Swift yet?

@carlynorama answering your questions

  1. build and compile is triggered from VSCode, not CLI
  2. no, the service should be in a vendor-directory with many support folders below
  3. pure swift
  4. problem is, the service will be long-running webservice. the support folders have to be easily accessible (2), because users can change them during runtime.
  5. .env ? no

This isn't what you asked for at all. I just am pretty strongly team don't mix build products and source files when you can avoid it, so you can ignore this all as you like. I think I might have a demo project that might help you set up your project a little differently, if you're open to that. But it may be wrong for you so just a few more questions:

  • What operating system is your server?
  • What version of Swift are you using? (How concurrency safe do you need to be)
  • Are these sub folders Source files or in anyway also used at compile time (not testing, during the compile)?

One of the possibilities includes putting the path to the user changeable files in a .env file in directory where the shell command to launch the process will be run from.

In VSCode/SPM that is the Package root by default.

If you don't want to go down the route of writing your own compile scripts, putting a .env file in that directory, adding it to .gitignore and then setting up a variable to the folder that you want to process in that is a way to keep your files and build products separate while still taking advantage of the defacto VSCode setup. It can also make your server config easier in the long run because the folder information isn't only compiled in the binary. The sysadmin can configure it on their end, too. (You can still have it work on the pwd as a default if no .env file is found)

I have a project that does that in a fairly rough and ready way that I can share. The way I have it written (dropping into the C rather than the Swift interface) won't work on Windows but I've been meaning to update that. There are also actual packages that offer that service in the SPI that'd probably be more supported in the long run. It's also part of Vapor and Hummingbird if you're using either of those.

Anyway, hope this helps, let me know if a demo project would be useful.

What kind of resources?

The Swift package manager supports the Bundle APIs for managing resources, without depending on specific file locations. See swift-evolution/proposals/0271-package-manager-resources.md at main · swiftlang/swift-evolution · GitHub