Skip to content

Commit

Permalink
[java-interop] Fix include directory specification
Browse files Browse the repository at this point in the history
Commit b6431ac broke the build of `src/java-interop`:

	Using task Exec from Microsoft.Build.Tasks.Exec, Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	Executing: gcc -g -shared -std=c99 -o "obj/libjava-interop-m32.dylib" -m32 -DDEBUG -DJI_DLL_EXPORT -DMONODEVELOP -DMONO_DLL_EXPORT -fvisibility=hidden -Wl,-undefined -Wl,suppress -Wl,-flat_namespace -L /Library/Frameworks/Mono.framework/Libraries -lmonosgen-2.0   jni.c java-interop.c java-interop-mono.c java-interop-gc-bridge-mono.c
	Environment variables being passed to the tool:
	jni.c:7:10: fatal error: 'jni.h' file not found
	#include <jni.h>
	         ^
	1 error generated.
	In file included from java-interop-mono.c:1:
	./java-interop-mono.h:30:11: fatal error: 'mono/metadata/assembly.h' file not found
	        #include <mono/metadata/assembly.h>
	                 ^
	1 error generated.

The problem? There's no `gcc -Ipath` option, so the compiler doesn't
know where to find `<jni.h>` or `<mono/metadata/assembly.h>`.

The `-I` values are derived from the `@(JdkIncludePath) and
`@(MonoIncludePath)` MSBuild item groups:

	<!-- via bin/BuildDebug/JdkInfo.props -->
	<PropertyGroup>
	  <JdkJvmPath Condition=" '$(JdkJvmPath)' == '' ">/Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/jre/lib/server/libjvm.dylib</JdkJvmPath>
	</PropertyGroup>
	<ItemGroup>
	  <JdkIncludePath Condition=" '$(JdkJvmPath)' == '' " Include="/Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/include" />
	  <JdkIncludePath Condition=" '$(JdkJvmPath)' == '' " Include="/Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/include/darwin" />
	</ItemGroup>

	<!-- via bin/BuildDebug/MonoInfo.props -->
	<PropertyGroup>
	  <MonoFrameworkPath Condition=" '$(MonoFrameworkPath)' == '' ">/Library/Frameworks/Mono.framework/Libraries/libmonosgen-2.0.1.dylib</MonoFrameworkPath>
	</PropertyGroup>
	<ItemGroup>
	  <MonoIncludePath Condition=" '$(MonoFrameworkPath)' == '' " Include="/Library/Frameworks/Mono.framework/Headers/mono-2.0" />
	</ItemGroup>

The *intent* to commit b6431ac is that if e.g. `$(JdkJvmPath)` is
overridden, then we shouldn't automatically generate the
`@(JdkIncludePath)` items, because they'll be for the "wrong" JDK.
If `$(JdkJvmPath)` is overridden, then `@(JdkIncludePath)` should be
as well. (Ditto `$(MonoFrameworkPath)` and `@(MonoIncludePath)`.)

The problem is [evaluation time][0]:

> During the evaluation phase of a build, imported files are
> incorporated into the build in the order in which they appear.
> Properties and items are defined in three passes in the following
> order:
>
> * Properties are defined and modified in the order in which they appear.
> * Item definitions are defined and modified in the order in which they appear.
> * Items are defined and modified in the order in which they appear.

Properties are *always* evaluated before items, meanine when it came
time to evaluate `//JdkIncludePath/@Condition`, `$(JdkJvmPath)` was
*always* defined, and thus `@(JdkIncludePath)` was *always* empty.

Which is why there are no instances of `gcc -I` in the `gcc` compile
line, and why those headers can't be found.

The fix is to instead use the `<Choose/>` element to ensure that the
default items are specified when the "controlling" property isn't
overridden:

	<!-- via bin/BuildDebug/JdkInfo.props -->
	<Choose>
	  <When Condition=" '$(JdkJvmPath)' == '' ">
	    <PropertyGroup>
	      <JdkJvmPath>/Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/jre/lib/server/libjvm.dylib</JdkJvmPath>
	    </PropertyGroup>
	    <ItemGroup>
	      <JdkIncludePath Include="/Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/include" />
	      <JdkIncludePath Include="/Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/include/darwin" />
	    </ItemGroup>
	  </When>
	</Choose>

	<!-- via bin/BuildDebug/MonoInfo.props -->
	<Choose>
	  <When Condition=" '$(MonoFrameworkPath)' == '' ">
	    <PropertyGroup>
	      <MonoFrameworkPath>/Library/Frameworks/Mono.framework/Libraries/libmonosgen-2.0.1.dylib</MonoFrameworkPath>
	      <MonoLibs         >-L /Library/Frameworks/Mono.framework/Libraries -lmonosgen-2.0</MonoLibs>
	    </PropertyGroup>
	    <ItemGroup>
	      <MonoIncludePath Include="/Library/Frameworks/Mono.framework/Headers/mono-2.0" />
	    </ItemGroup>
	  </When>
	</Choose>

This allows `@(JdkIncludePath)` and `@(MonoIncludePath)` to have
values when `$(JdkJvmPath)` and `$(MonoFrameworkPath)` aren't
overridden, which in turn allows `gcc -I` to be used, and allows
`src/java-interop` to build.

[0]: https://msdn.microsoft.com/en-us/library/dd997067.aspx#Anchor_2
  • Loading branch information
jonpryor committed Jun 22, 2016
1 parent 6fc9c69 commit 206e4cd
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 13 deletions.
16 changes: 10 additions & 6 deletions build-tools/scripts/jdk.mk
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,16 @@ bin/Build$(CONFIGURATION)/JdkInfo.props: $(JI_JDK_INCLUDE_PATHS) $(JI_JVM_PATH)
-mkdir -p `dirname "$@"`
-rm "$@"
echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' > "$@"
echo ' <PropertyGroup>' >> "$@"
echo " <JdkJvmPath Condition=\" '\$$(JdkJvmPath)' == '' \">$(JI_JVM_PATH)</JdkJvmPath>" >> "$@"
echo ' </PropertyGroup>' >> "$@"
echo ' <ItemGroup>' >> "$@"
echo ' <Choose>' >> "$@"
echo " <When Condition=\" '\$$(JdkJvmPath)' == '' \">" >> "$@"
echo ' <PropertyGroup>' >> "$@"
echo " <JdkJvmPath>$(JI_JVM_PATH)</JdkJvmPath>" >> "$@"
echo ' </PropertyGroup>' >> "$@"
echo ' <ItemGroup>' >> "$@"
for p in $(JI_JDK_INCLUDE_PATHS); do \
echo " <JdkIncludePath Condition=\" '\$$(JdkJvmPath)' == '' \" Include=\"$$p\" />" >> "$@"; \
echo " <JdkIncludePath Include=\"$$p\" />" >> "$@"; \
done
echo ' </ItemGroup>' >> "$@"
echo ' </ItemGroup>' >> "$@"
echo ' </When>' >> "$@"
echo ' </Choose>' >> "$@"
echo '</Project>' >> "$@"
18 changes: 11 additions & 7 deletions build-tools/scripts/mono.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ bin/Build$(CONFIGURATION)/MonoInfo.props: $(JI_MONO_INCLUDE_PATHS) $(JI_MONO_FRA
-mkdir -p `dirname "$@"`
-rm "$@"
echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' > "$@"
echo ' <PropertyGroup>' >> "$@"
echo " <MonoFrameworkPath Condition=\" '\$$(MonoFrameworkPath)' == '' \">$(JI_MONO_FRAMEWORK_PATH)</MonoFrameworkPath>" >> "$@"
echo " <MonoLibs Condition=\" '\$$(MonoLibs)' == '' \">$(JI_MONO_LIBS)</MonoLibs>" >> "$@"
echo ' </PropertyGroup>' >> "$@"
echo ' <ItemGroup>' >> "$@"
echo ' <Choose>' >> "$@"
echo " <When Condition=\" '\$$(MonoFrameworkPath)' == '' \">" >> "$@"
echo ' <PropertyGroup>' >> "$@"
echo " <MonoFrameworkPath>$(JI_MONO_FRAMEWORK_PATH)</MonoFrameworkPath>" >> "$@"
echo " <MonoLibs >$(JI_MONO_LIBS)</MonoLibs>" >> "$@"
echo ' </PropertyGroup>' >> "$@"
echo ' <ItemGroup>' >> "$@"
for p in $(JI_MONO_INCLUDE_PATHS); do \
echo " <MonoIncludePath Condition=\" '\$$(MonoFrameworkPath)' == '' \" Include=\"$$p\" />" >> "$@"; \
echo " <MonoIncludePath Include=\"$$p\" />" >> "$@"; \
done
echo ' </ItemGroup>' >> "$@"
echo ' </ItemGroup>' >> "$@"
echo ' </When>' >> "$@"
echo ' </Choose>' >> "$@"
echo '</Project>' >> "$@"

0 comments on commit 206e4cd

Please sign in to comment.