From de1ff5bf53abe1139f9579e29caeff547b405996 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 22 Jun 2016 12:35:07 -0400 Subject: [PATCH] [java-interop] Fix include directory specification Commit b6431ac8 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 ^ 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 ^ 1 error generated. The problem? There's no `gcc -Ipath` option, so the compiler doesn't know where to find `` or ``. The `-I` values are derived from the `@(JdkIncludePath) and `@(MonoIncludePath)` MSBuild item groups: /Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/jre/lib/server/libjvm.dylib /Library/Frameworks/Mono.framework/Libraries/libmonosgen-2.0.1.dylib The *intent* to commit b6431ac8 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, meaning 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 `` element to ensure that the default items are specified when the "controlling" property isn't overridden: /Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/jre/lib/server/libjvm.dylib /Library/Frameworks/Mono.framework/Libraries/libmonosgen-2.0.1.dylib -L /Library/Frameworks/Mono.framework/Libraries -lmonosgen-2.0 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 --- build-tools/scripts/jdk.mk | 16 ++++++++++------ build-tools/scripts/mono.mk | 18 +++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/build-tools/scripts/jdk.mk b/build-tools/scripts/jdk.mk index 1a876e006..af8303258 100644 --- a/build-tools/scripts/jdk.mk +++ b/build-tools/scripts/jdk.mk @@ -115,12 +115,16 @@ bin/Build$(CONFIGURATION)/JdkInfo.props: $(JI_JDK_INCLUDE_PATHS) $(JI_JVM_PATH) -mkdir -p `dirname "$@"` -rm "$@" echo '' > "$@" - echo ' ' >> "$@" - echo " $(JI_JVM_PATH)" >> "$@" - echo ' ' >> "$@" - echo ' ' >> "$@" + echo ' ' >> "$@" + echo " " >> "$@" + echo ' ' >> "$@" + echo " $(JI_JVM_PATH)" >> "$@" + echo ' ' >> "$@" + echo ' ' >> "$@" for p in $(JI_JDK_INCLUDE_PATHS); do \ - echo " " >> "$@"; \ + echo " " >> "$@"; \ done - echo ' ' >> "$@" + echo ' ' >> "$@" + echo ' ' >> "$@" + echo ' ' >> "$@" echo '' >> "$@" diff --git a/build-tools/scripts/mono.mk b/build-tools/scripts/mono.mk index 0dac4088e..0ecde143a 100644 --- a/build-tools/scripts/mono.mk +++ b/build-tools/scripts/mono.mk @@ -20,13 +20,17 @@ bin/Build$(CONFIGURATION)/MonoInfo.props: $(JI_MONO_INCLUDE_PATHS) $(JI_MONO_FRA -mkdir -p `dirname "$@"` -rm "$@" echo '' > "$@" - echo ' ' >> "$@" - echo " $(JI_MONO_FRAMEWORK_PATH)" >> "$@" - echo " $(JI_MONO_LIBS)" >> "$@" - echo ' ' >> "$@" - echo ' ' >> "$@" + echo ' ' >> "$@" + echo " " >> "$@" + echo ' ' >> "$@" + echo " $(JI_MONO_FRAMEWORK_PATH)" >> "$@" + echo " $(JI_MONO_LIBS)" >> "$@" + echo ' ' >> "$@" + echo ' ' >> "$@" for p in $(JI_MONO_INCLUDE_PATHS); do \ - echo " " >> "$@"; \ + echo " " >> "$@"; \ done - echo ' ' >> "$@" + echo ' ' >> "$@" + echo ' ' >> "$@" + echo ' ' >> "$@" echo '' >> "$@"