2

I have a scala project that uses macros which basically follows the exact method described here (http://www.scala-sbt.org/0.12.4/docs/Detailed-Topics/Macro-Projects.html) including the whole Distribution section (so in essence I have a root project, and a subproject called macro which holds the macros being used)

The problem is, when I publish my project (using publish-local for now), and another scala project uses the one with a macro as a dependency, it tries to pull macro#macro_2.10;0.1-SNAPSHOT since it appears in the POM. This causes project to fail to compile as it can't resolve the dependency, i.e.

> compile
[info] Updating {file:/Users/mdedetrich/silvermanwylie/waitress/}default-0e4b9d...
[info] Resolving macro#macro_2.10;0.1-SNAPSHOT ...
[warn]  module not found: macro#macro_2.10;0.1-SNAPSHOT
[warn] ==== local: tried
[warn]   /Users/mdedetrich/.ivy2/local/macro/macro_2.10/0.1-SNAPSHOT/ivys/ivy.xml
[warn] ==== public: tried
[warn]   http://repo1.maven.org/maven2/macro/macro_2.10/0.1-SNAPSHOT/macro_2.10-0.1-SNAPSHOT.pom
[info] Resolving org.slf4j#slf4j-api;1.6.4 ...
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: macro#macro_2.10;0.1-SNAPSHOT: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[trace] Stack trace suppressed: run last *:update for the full output.
[error] (*:update) sbt.ResolveException: unresolved dependency: macro#macro_2.10;0.1-SNAPSHOT: not found
[error] Total time: 0 s, completed Aug 23, 2013 8:15:56 PM

If I manually remove the dependency from ivy-1.0.0-SNAPSHOT.xml

<dependency org="macro" name="macro_2.10" rev="0.1-SNAPSHOT" conf="compile->default(compile)"/>

In ivy cache then everything works fine (the project compiles and the macro it is using from the dependency works fine)

This is what my Build.scala looks like

import sbt._
import Keys._

object MacroBuild extends Build {
  lazy val main = Project("main", file(".")) dependsOn(macroSub) settings(
    // include the macro classes and resources in the main jar
    mappings in (Compile, packageBin) <++= mappings in (macroSub, Compile, packageBin),
    // include the macro sources in the main source jar
    mappings in (Compile, packageSrc) <++= mappings in (macroSub, Compile, packageSrc)
  )
  lazy val macroSub = Project("macro", file("macro")) settings(
    scalaVersion:= "2.10.2",
    libraryDependencies <+= scalaVersion("org.scala-lang" % "scala-compiler" % _),
    publish := {},
    publishLocal := {}
   )
}

How do I prevent the macro dependency from appearing in the POM?

EDIT: Just to be clear, the issue is not with scala-language or scala-reflect being included as a dependency, the issue is with the main (or root) project depending on the macro sub project when it never actually needs or uses it (since its a macro)

mdedetrich
  • 1,899
  • 1
  • 18
  • 29
  • You don't have to depend on scala-compiler. Just scala-reflect is enough for macros. – Eugene Burmako Aug 23 '13 at 17:30
  • Also you could try this: scalaVersion("org.scala-lang" % "scala-reflect" % _ % "provided"). This should remove the mention of dependency from the POM. For more details take a look at https://github.com/xeno-by/sbt-example-paradise210/issues/1. – Eugene Burmako Aug 23 '13 at 17:39
  • The provided method didn't work, the issue isn't with scala-compiler or scala-reflect, the issue is with the main project depending on the macro sub project in the dependencies in the POM Just updated question to reflect this – mdedetrich Aug 23 '13 at 23:27
  • Thanks, it worked when I updated my sbt and build.scala. – M.Rez Sep 09 '16 at 15:17

2 Answers2

7

In your main project definition, you can replace dependsOn(macroSub) with dependsOn(macroSub % "compile-internal"). This won't add the macro project as a dependency to the POM.

ingoem
  • 425
  • 4
  • 6
  • Note: if you use the macros in tests, you have to have `"macroSub % "compile-internal, test-internal"` for compilation of tests to succeed. – Rex Kerr Apr 07 '16 at 16:02
0

The Build.scala in the linked document is a multi-project build:

import sbt._
import Keys._

object MacroBuild extends Build {
   lazy val main = Project("main", file(".")) dependsOn(macroSub)
   lazy val macroSub = Project("macro", file("macro")) settings(
      libraryDependencies <+= scalaVersion("org.scala-lang" % "scala-compiler" % _)
   )
}

This means that the macro class files will be in another jar, and you have to publish (or publish-local) both your main project and the macro project if other project wants to use it.

> project macro
> publish-local
Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319
  • Ok, that worked fine, but its still confusing. Why do you need to publish the macro dependency if its never actually used by the project? Why does the documentation, under Distribution, specify to overwrite the publish and publish-local commands for the macro subproject. It implies that even though technically speaking the macro is a subproject, its only that way due to how macro compilation and works, and that macro sub project should never be published (which is why its overwritten...) – mdedetrich Aug 23 '13 at 23:19