mirror of
https://github.com/KarolS/millfork.git
synced 2025-04-08 03:37:03 +00:00
Detection of the default include path.
This commit is contained in:
parent
7bf9616fcb
commit
438d8dbe6e
@ -8,6 +8,8 @@
|
||||
|
||||
* Unified the syntax of commandline switches.
|
||||
|
||||
* Automatic detection of the standard include path.
|
||||
|
||||
* Added aliases.
|
||||
|
||||
* Added enumeration types.
|
||||
|
@ -28,7 +28,12 @@ no extension for BBC micro program file,
|
||||
|
||||
* `-g` – Generate also the label file. The label file contains labels with their addresses, with duplicates removed. It can be loaded into the monitor of the Vice emulator for debugging purposes. The file has the same name as the output file and the extension is `.lbl`.
|
||||
|
||||
* `-I <dir>;<dir>` – The include directories. The current working directory is also an include directory. Those directories are searched for modules and platform definitions.
|
||||
* `-I <dir>;<dir>` – The include directories.
|
||||
Those directories are searched for modules and platform definitions.
|
||||
When searching for modules, the directory containing the file currently being compiled is also searched.
|
||||
When searching for platform definitions, the current working directory is also searched.
|
||||
If not given, the compiler will try to detect the default include directory.
|
||||
If given, then the compiler will NOT try to detect the default include directory and you will have to add it to the list yourself.
|
||||
|
||||
* `-t <platform>` – Target platform. It is loaded from an `.ini` file found in any of the include directories. See also [this document](target-platforms.md).
|
||||
|
||||
|
@ -18,7 +18,7 @@ void main(){
|
||||
Compile it using the following commandline:
|
||||
|
||||
```
|
||||
java -jar millfork.jar hello_world.mfk -o hello_world -t c64 -I path_to_millfork\include
|
||||
java -jar millfork.jar hello_world.mfk -o hello_world -t c64
|
||||
```
|
||||
|
||||
Run the output executable (here using the VICE emulator):
|
||||
@ -27,15 +27,13 @@ Run the output executable (here using the VICE emulator):
|
||||
x64 hello_world.prg
|
||||
```
|
||||
|
||||
## Basic commandline usage
|
||||
## Basic command-line usage
|
||||
|
||||
The following options are crucial when compiling your sources:
|
||||
The following options are obligatory when compiling your sources:
|
||||
|
||||
* `-o FILENAME` – specifies the base name for your output file, an appropriate file extension will be appended (`prg` for Commodore, `xex` for Atari computers, `a2` for Apple, `asm` for assembly output, `lbl` for label file, `inf` for BBC file metadata, `dsk` for PC-88, `tap` for ZX Spectrum, `nes` for Famicom, `bin` for Atari 2600)
|
||||
|
||||
* `-I DIR;DIR;DIR;...` – specifies the paths to directories with modules to include.
|
||||
|
||||
* `-t PLATFORM` – specifies the target platform (`c64` is the default). Each platform is defined in an `.ini` file in the include directory. For the list of supported platforms, see [Supported platforms](target-platforms.md)
|
||||
* `-t PLATFORM` – specifies the target platform. Each platform is defined in an `.ini` file in the include directory. For the list of supported platforms, see [Supported platforms](target-platforms.md)
|
||||
|
||||
You may be also interested in the following:
|
||||
|
||||
@ -57,3 +55,5 @@ You may be also interested in the following:
|
||||
* `-Wall` – enable all warnings
|
||||
|
||||
* `--help` – list all commandline options
|
||||
|
||||
For the comprehensive list of command-line options, see [Command-line options](./command-line.md).
|
||||
|
@ -1,5 +1,6 @@
|
||||
package millfork
|
||||
|
||||
import java.io.File
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.{Files, Paths}
|
||||
import java.util.Locale
|
||||
@ -58,7 +59,7 @@ object Main {
|
||||
}
|
||||
|
||||
val startTime = System.nanoTime()
|
||||
val (status, c) = parser(errorReporting).parse(Context(errorReporting, Nil), args.toList)
|
||||
val (status, c0) = parser(errorReporting).parse(Context(errorReporting, Nil), args.toList)
|
||||
status match {
|
||||
case CliStatus.Quit => return
|
||||
case CliStatus.Failed =>
|
||||
@ -66,18 +67,22 @@ object Main {
|
||||
case CliStatus.Ok => ()
|
||||
}
|
||||
errorReporting.assertNoErrors("Invalid command line")
|
||||
if (c.inputFileNames.isEmpty) {
|
||||
errorReporting.verbosity = c0.verbosity.getOrElse(0)
|
||||
if (c0.inputFileNames.isEmpty) {
|
||||
errorReporting.fatalQuit("No input files")
|
||||
}
|
||||
errorReporting.verbosity = c.verbosity.getOrElse(0)
|
||||
|
||||
errorReporting.debug("millfork version " + BuildInfo.version)
|
||||
errorReporting.trace(s"Copyright (C) $copyrightYears Karol Stasiak")
|
||||
errorReporting.trace("This program comes with ABSOLUTELY NO WARRANTY.")
|
||||
errorReporting.trace("This is free software, and you are welcome to redistribute it under certain conditions")
|
||||
errorReporting.trace("You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/")
|
||||
val c = fixMissingIncludePath(c0)
|
||||
if (c.includePath.isEmpty) {
|
||||
errorReporting.warn("Failed to detect the default include directory, consider using the -I option")
|
||||
}
|
||||
|
||||
val platform = Platform.lookupPlatformFile(c.includePath, c.platform.getOrElse {
|
||||
val platform = Platform.lookupPlatformFile("." :: c.includePath, c.platform.getOrElse {
|
||||
errorReporting.info("No platform selected, defaulting to `c64`")
|
||||
"c64"
|
||||
})
|
||||
@ -149,6 +154,55 @@ object Main {
|
||||
}
|
||||
}
|
||||
|
||||
private def getDefaultIncludePath: Either[String, String] = {
|
||||
try {
|
||||
var where = new File(getClass.getProtectionDomain.getCodeSource.getLocation.toURI).getParentFile
|
||||
if ((where.getName == "scala-2.12" || where.getName == "scala-2.13") && where.getParentFile.getName == "target") {
|
||||
where = where.getParentFile.getParentFile
|
||||
}
|
||||
val dir = new File(where.getAbsolutePath + File.separatorChar + "include")
|
||||
if (dir.exists()) {
|
||||
Right(dir.getAbsolutePath)
|
||||
} else {
|
||||
Left(s"The ${dir.getAbsolutePath} directory doesn't exist")
|
||||
}
|
||||
} catch {
|
||||
case e: Exception => Left(e.getMessage)
|
||||
}
|
||||
}
|
||||
|
||||
private def getAllDefaultPlatforms: Seq[String] = {
|
||||
(getDefaultIncludePath match {
|
||||
case Left(_) => Seq(
|
||||
"c64", "c64_scpu", "c64_scpu16", "c64_crt9k", "c64_crt16k", "lunix",
|
||||
"vic20", "vic20_3k", "vic20_8k", "vic20_a000",
|
||||
"c16", "plus4", "pet", "c128",
|
||||
"a8", "bbcmicro", "apple2",
|
||||
"nes_mmc4", "nes_small", "vcs",
|
||||
"zxspectrum", "zxspectrum_8080", "pc88", "cpc464",
|
||||
"cpm", "cpm_z80")
|
||||
case Right(path) =>
|
||||
Seq(new File(".").list(), new File(path).list())
|
||||
.filter(_ ne null)
|
||||
.flatMap(_.toSeq)
|
||||
.filter(_.endsWith(".ini"))
|
||||
.map(_.stripSuffix(".ini"))
|
||||
}).sorted
|
||||
}
|
||||
|
||||
private def fixMissingIncludePath(c: Context)(implicit log: Logger): Context = {
|
||||
if (c.includePath.isEmpty) {
|
||||
getDefaultIncludePath match {
|
||||
case Left(err) =>
|
||||
log.debug(s"Failed to find the default include path: $err")
|
||||
case Right(path) =>
|
||||
log.debug(s"Automatically detected include path: $path")
|
||||
return c.copy(includePath = List(path))
|
||||
}
|
||||
}
|
||||
c
|
||||
}
|
||||
|
||||
private def assembleForMos(c: Context, platform: Platform, options: CompilationOptions): AssemblerOutput = {
|
||||
val optLevel = c.optimizationLevel.getOrElse(0)
|
||||
val unoptimized = new MosSourceLoadingQueue(
|
||||
@ -260,12 +314,12 @@ object Main {
|
||||
parameter("-t", "--target").placeholder("<platform>").action { (p, c) =>
|
||||
assertNone(c.platform, "Platform already defined")
|
||||
c.copy(platform = Some(p))
|
||||
}.description("Target platform, any of: c64, c16, plus4, vic20, vic20_3k, vic20_8k, pet, c128, a8, bbc, apple2, nes_mmc4, nes_small, c64_scpu, c64_scpu16, vcs.")
|
||||
}.description(s"Target platform, any of:\n${getAllDefaultPlatforms.grouped(10).map(_.mkString(", ")).mkString(",\n")}.")
|
||||
|
||||
parameter("-I", "--include-dir").repeatable().placeholder("<dir>;<dir>;...").action { (paths, c) =>
|
||||
val n = paths.split(";")
|
||||
c.copy(includePath = c.includePath ++ n)
|
||||
}.description("Include paths for modules.")
|
||||
}.description("Include paths for modules. If not given, the default path is used: " + getDefaultIncludePath.fold(identity, identity))
|
||||
|
||||
parameter("-r", "--run").placeholder("<program>").action { (p, c) =>
|
||||
assertNone(c.runFileName, "Run program already defined")
|
||||
@ -432,7 +486,7 @@ object Main {
|
||||
assertNone(c.optimizationLevel, "Optimization level already defined")
|
||||
c.copy(optimizationLevel = Some(i))
|
||||
}.description("Optimize code even more.")
|
||||
if (i == 1 || i > 3) f.hidden()
|
||||
if (i == 1 || i > 4) f.hidden()
|
||||
}
|
||||
flag("--inline").action { c =>
|
||||
c.changeFlag(CompilationFlag.InlineFunctions, true)
|
||||
|
@ -6,13 +6,17 @@ package millfork.cli
|
||||
trait CliOption[T, O <: CliOption[T, O]] {
|
||||
this: O =>
|
||||
def toStrings(firstTab: Int): List[String] = {
|
||||
@inline
|
||||
def indent(s: String):String = "".padTo(firstTab, ' ') + s
|
||||
val fl = firstLine
|
||||
if (_description == "") {
|
||||
List(fl)
|
||||
} else if (fl.length < firstTab) {
|
||||
List(fl.padTo(firstTab, ' ') + _description)
|
||||
return List(fl)
|
||||
}
|
||||
val descriptionLines = _description.split("\n")
|
||||
if (fl.length < firstTab) {
|
||||
(fl.padTo(firstTab, ' ') + descriptionLines.head) :: descriptionLines.tail.map(indent).toList
|
||||
} else {
|
||||
List(fl, "".padTo(firstTab, ' ') + _description)
|
||||
fl :: descriptionLines.map(indent).toList
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user