8338290: Xcode project generator for hotspot

Co-authored-by: Gerard Ziemski <gziemski@openjdk.org>
Co-authored-by: Magnus Ihse Bursie <ihse@openjdk.org>
Reviewed-by: azafari, erikj
This commit is contained in:
Magnus Ihse Bursie 2024-08-22 10:31:34 +00:00
parent 6644dd33f6
commit 129f527f4f
15 changed files with 1773 additions and 16 deletions

View File

@ -278,6 +278,18 @@ $(eval $(call SetupTarget, eclipse-mixed-env, \
ARGS := --always-make, \
))
$(eval $(call SetupTarget, hotspot-xcode-project, \
MAKEFILE := ide/xcode/hotspot/CreateXcodeProject, \
TARGET := build, \
DEPS := hotspot compile-commands-hotspot jdk-image, \
))
$(eval $(call SetupTarget, open-hotspot-xcode-project, \
MAKEFILE := ide/xcode/hotspot/CreateXcodeProject, \
TARGET := open, \
DEPS := hotspot-xcode-project, \
))
ALL_TARGETS += $(HOTSPOT_VARIANT_TARGETS) $(HOTSPOT_VARIANT_GENSRC_TARGETS) \
$(HOTSPOT_VARIANT_LIBS_TARGETS) $(HOTSPOT_VARIANT_STATIC_LIBS_TARGETS)

View File

@ -189,6 +189,11 @@ else
endef
endif
define copy-and-chmod-executable
$(install-file)
$(CHMOD) a+rx $@
endef
################################################################################
# Recursive wildcard function. Walks down directories recursively and matches

View File

@ -222,7 +222,7 @@ define SetupNativeCompilationBody
ifeq ($(GENERATE_COMPILE_COMMANDS_ONLY), true)
# Override all targets (this is a hack)
$1 := $$($1_ALL_OBJS_JSON)
$1 := $$($1_ALL_OBJS_JSON) $$($1_LDFLAGS_FILE)
endif
endef

View File

@ -198,4 +198,16 @@ define CreateDynamicLibraryOrExecutable
$(CODESIGN) -f -s $$($1_CODESIGN_OPTS) --entitlements \
$$(call GetEntitlementsFile, $$@) $$@)
endif
# This is for IDE integration purposes only, and is not normally generated
$1_LDFLAGS_FILE := $$(MAKESUPPORT_OUTPUTDIR)/compile-commands/$$($1_NAME)-ldflags.txt
$1_ALL_LD_ARGS := $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
$$($1_LIBS) $$($1_EXTRA_LIBS)
$$($1_LDFLAGS_FILE): $$($1_VARDEPS_FILE)
$$(call LogInfo, Creating compile commands linker flags output for $$($1_BASENAME))
$$(call MakeDir, $$(dir $$@))
$$(ECHO) $$($1_ALL_LD_ARGS) > $$@
endef

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -83,7 +83,7 @@ ifeq ($(call isTargetOs, windows), true)
################################################################################
# Build the ProjectCreator java tool.
TOOLS_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/support/ide_classes
TOOLS_OUTPUTDIR := $(MAKESUPPORT_OUTPUTDIR)/ide/visualstudio
$(eval $(call SetupJavaCompilation, BUILD_PROJECT_CREATOR, \
TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \

View File

@ -0,0 +1,112 @@
#
# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# This must be the first rule
default: all
include $(SPEC)
include MakeBase.gmk
include CopyFiles.gmk
include Execute.gmk
include JavaCompilation.gmk
ifeq ($(call isTargetOs, macosx), true)
##############################################################################
# Build the XcodeProjectMaker java tool.
PROJECT_MAKER_DIR := $(TOPDIR)/make/ide/xcode/hotspot
TOOLS_OUTPUTDIR := $(MAKESUPPORT_OUTPUTDIR)/ide/xcode
IDE_OUTPUTDIR := $(OUTPUTDIR)/xcode
PROJECT_FILE_NAME := hotspot.xcodeproj
COMPILE_COMMAND_FILE := $(OUTPUTDIR)/compile_commands.json
LINKER_FLAGS_FILE := $(MAKESUPPORT_OUTPUTDIR)/compile-commands/jvm-ldflags.txt
$(eval $(call SetupJavaCompilation, BUILD_PROJECT_CREATOR, \
TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \
SRC := $(PROJECT_MAKER_DIR)/src/classes, \
BIN := $(TOOLS_OUTPUTDIR), \
DISABLED_WARNINGS := rawtypes unchecked serial, \
))
TARGETS += $(BUILD_PROJECT_CREATOR)
# Run the XcodeProjectMaker tool
PROJECT_CREATOR_TOOL := $(JAVA_SMALL) -cp $(TOOLS_OUTPUTDIR) XcodeProjectMaker
ifneq ($(findstring $(LOG_LEVEL), debug trace), )
XCODE_PROJ_DEBUG_OPTION := -d
endif
XCODE_PROJ_VARDEPS := $(WORKSPACE_ROOT) $(IDE_OUTPUTDIR) \
$(PROJECT_MAKER_DIR)/data $(COMPILE_COMMAND_FILE) $(LINKER_FLAGS_FILE)
XCODE_PROJ_VARDEPS_FILE := $(call DependOnVariable, XCODE_PROJ_VARDEPS, \
$(TOOLS_OUTPUTDIR)/xcodeproj.vardeps)
$(eval $(call SetupExecute, build_xcode_project, \
WARN := Generating Xcode project file, \
DEPS := $(BUILD_PROJECT_CREATOR) $(COMPILE_COMMAND_FILE) \
$(LINKER_FLAGS_FILE) $(XCODE_PROJ_VARDEPS_FILE), \
OUTPUT_DIR := $(TOOLS_OUTPUTDIR), \
COMMAND := $(PROJECT_CREATOR_TOOL) $(WORKSPACE_ROOT) $(IDE_OUTPUTDIR) \
$(PROJECT_MAKER_DIR)/data $(COMPILE_COMMAND_FILE) \
$(LINKER_FLAGS_FILE) $(XCODE_PROJ_DEBUG_OPTION), \
))
TARGETS += $(build_xcode_project)
$(eval $(call SetupCopyFiles, copy_xcode_project, \
DEST := $(IDE_OUTPUTDIR), \
FILES := $(PROJECT_MAKER_DIR)/data/script_before.sh $(PROJECT_MAKER_DIR)/data/script_after.sh , \
MACRO := copy-and-chmod-executable, \
))
TARGETS += $(copy_xcode_project)
$(eval $(call SetupExecute, open_xcode_project, \
INFO := Opening Xcode project file, \
DEPS := $(build_xcodeproject_TARGET) FORCE, \
OUTPUT_DIR := $(TOOLS_OUTPUTDIR), \
COMMAND := open $(IDE_OUTPUTDIR)/$(PROJECT_FILE_NAME), \
))
TARGETS += $(open_xcode_project)
# Always call open without considering dependencies being up to date
FORCE:
build: $(build_xcode_project) $(copy_xcode_project)
open: $(open_xcode_project)
all: $(TARGETS)
else
build:
open:
all:
$(info Xcode projects are only supported on macOS)
endif
.PHONY: default all build open

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "4"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "Yes"
symbolName = "load_jimage_library"
moduleName = "libjvm.dylib">
<Actions>
<BreakpointActionProxy
ActionExtensionID = "Xcode.BreakpointAction.DebuggerCommand">
<ActionContent
consoleCommand = "process handle -n true -p true -s false SIGSEGV SIGBUS SIGUSR2">
</ActionContent>
</BreakpointActionProxy>
</Actions>
<Locations>
<Location
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "ClassLoader::load_jimage_library()"
moduleName = "libjvm.dylib"
usesParentBreakpointCondition = "Yes"
timestampString = "0"
startingColumnNumber = "0"
endingColumnNumber = "0"
startingLineNumber = "0"
endingLineNumber = "0"
offsetFromSymbolStart = "0">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D60000000000000000000000"
BuildableName = "libjvm.dylib"
BlueprintName = "jvm"
ReferencedContainer = "container:hotspot.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D60000000000000000000000"
BuildableName = "libjvm.dylib"
BlueprintName = "jvm"
ReferencedContainer = "container:hotspot.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<PathRunnable
runnableDebuggingMode = "0"
FilePath = "TEMPLATE_JDK_PATH/build/jdk/bin/java">
</PathRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D60000000000000000000000"
BuildableName = "libjvm.dylib"
BlueprintName = "jvm"
ReferencedContainer = "container:hotspot.xcodeproj">
</BuildableReference>
</MacroExpansion>
<CommandLineArguments>
<CommandLineArgument
argument = "-version"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<EnvironmentVariables>
<EnvironmentVariable
key = "DYLD_PRINT_ENV"
value = "1"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<PathRunnable
runnableDebuggingMode = "0"
FilePath = "TEMPLATE_JDK_PATH/build/jdk/bin/java">
</PathRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D60000000000000000000000"
BuildableName = "libjvm.dylib"
BlueprintName = "jvm"
ReferencedContainer = "container:hotspot.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Release">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,207 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 48;
objects = {
/* Begin PBXBuildFile section */
TEMPLATE_PBXBUILDFILE
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
D60000000000000000000003 /* script_before.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = script_before.sh; sourceTree = "<group>"; };
D60000000000000000000002 /* script_after.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = script_after.sh; sourceTree = "<group>"; };
D60000000000000000000006 /* libjvm.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libjvm.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
TEMPLATE_PBXFILEREFERENCE
/* End PBXFileReference section */
/* Begin PBXGroup section */
D60000000000000000000004 /* scripts */ = {
isa = PBXGroup;
children = (
D60000000000000000000003 /* script_before.sh */,
D60000000000000000000002 /* script_after.sh */,
);
name = scripts;
sourceTree = "<group>";
};
D60000000000000000000005 /* Products */ = {
isa = PBXGroup;
children = (
D60000000000000000000006 /* libjvm.dylib */,
);
name = Products;
sourceTree = "<group>";
};
D60000000000000000000001 = {
isa = PBXGroup;
children = (
D60000000000000000000004 /* scripts */,
TEMPLATE_GROUP_GENSRC /* gensrc */,
TEMPLATE_GROUP_SRC /* src */,
TEMPLATE_GROUP_TEST /* test */,
D60000000000000000000005 /* Products */,
);
sourceTree = "<group>";
};
TEMPLATE_GROUPS
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
D60000000000000000000000 /* jvm */ = {
isa = PBXNativeTarget;
buildConfigurationList = D6000000000000000000000F /* Build configuration list for PBXNativeTarget "jvm" */;
buildPhases = (
D60000000000000000000007 /* Run script_before */,
D60000000000000000000008 /* Sources */,
D6000000000000000000000A /* Run script_after */,
);
buildRules = (
);
dependencies = (
);
name = jvm;
productName = jvm;
productReference = D60000000000000000000006 /* libjvm.dylib */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
D60000000000000000000010 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = Oracle;
TargetAttributes = {
D60000000000000000000000 = {
CreatedOnToolsVersion = 9.0;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = D6000000000000000000000E /* Build configuration list for PBXProject "jvm" */;
compatibilityVersion = "Xcode 8.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = D60000000000000000000001;
productRefGroup = D60000000000000000000005 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
D60000000000000000000000 /* jvm */,
);
};
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
D60000000000000000000007 /* Run script_before */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run script_before";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cd $PROJECT_DIR;\ntime ./script_before.sh;\n";
};
D6000000000000000000000A /* Run script_after */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run script_after";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cd $PROJECT_DIR;\ntime ./script_after.sh;\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
D60000000000000000000008 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
TEMPLATE_PBXSOURCESSBUILDPHASE
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
D6000000000000000000000B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CODE_SIGN_IDENTITY = "-";
CONFIGURATION_BUILD_DIR = build/jdk/lib/server;
CONFIGURATION_TEMP_DIR = build;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
MTL_ENABLE_DEBUG_INFO = NO;
OBJROOT = build;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Release;
};
D6000000000000000000000D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
EXECUTABLE_PREFIX = lib;
FRAMEWORK_SEARCH_PATHS = (
TEMPLATE_FRAMEWORK_SEARCH_PATHS
);
OTHER_CFLAGS = (
TEMPLATE_OTHER_CFLAGS
);
OTHER_LDFLAGS = (
TEMPLATE_OTHER_LDFLAGS
);
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SYMROOT = build/jdk/lib/server;
USER_HEADER_SEARCH_PATHS = (
TEMPLATE_USER_HEADER_SEARCH_PATHS
);
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
D6000000000000000000000E /* Build configuration list for PBXProject "jvm" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D6000000000000000000000B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D6000000000000000000000F /* Build configuration list for PBXNativeTarget "jvm" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D6000000000000000000000D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = D60000000000000000000010 /* Project object */;
}

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = " NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D60000000000000000000000"
BuildableName = "libjvm.dylib"
BlueprintName = "jvm"
ReferencedContainer = "container:hotspot.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D60000000000000000000000"
BuildableName = "libjvm.dylib"
BlueprintName = "jvm"
ReferencedContainer = "container:hotspot.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<PathRunnable
runnableDebuggingMode = "0"
FilePath = "TEMPLATE_JDK_PATH/build/jdk/bin/java">
</PathRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D60000000000000000000000"
BuildableName = "libjvm.dylib"
BlueprintName = "jvm"
ReferencedContainer = "container:hotspot.xcodeproj">
</BuildableReference>
</MacroExpansion>
<CommandLineArguments>
<CommandLineArgument
argument = "-jar TEMPLATE_JDK_PATH/build/jdk/demo/jfc/J2Ddemo/J2Ddemo.jar"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<EnvironmentVariables>
<EnvironmentVariable
key = "DYLD_PRINT_ENV"
value = "1"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<PathRunnable
runnableDebuggingMode = "0"
FilePath = "TEMPLATE_JDK_PATH/build/jdk/bin/java">
</PathRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D60000000000000000000000"
BuildableName = "libjvm.dylib"
BlueprintName = "jvm"
ReferencedContainer = "container:hotspot.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Release">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,34 @@
#!/bin/bash
#
# Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
echo "running script_after.sh"
readonly JDK_LIB_PATH="build/jdk/lib/server/libjvm.dylib";
if [ ! -f ${JDK_LIB_PATH} ] ; then
{
echo ">>>>>>> Cannot find ${JDK_LIB_PATH}, the build failed!?";
exit 1;
}
fi

View File

@ -0,0 +1,67 @@
#!/bin/bash
#
# Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
echo "running script_before.sh"
readonly JDK_BUILD_PATH="..";
readonly JAVAC_LOCATE_PATTERN="images/jdk/bin/javac";
readonly HOTSPOT_TOUCH_FILE="../../../src/hotspot/os/posix/jvm_posix.cpp";
echo ">>>>>>> Making a copy of JDK ...";
javac_file_array=( $(find ${JDK_BUILD_PATH} | grep ${JAVAC_LOCATE_PATTERN}) );
javac_file=${javac_file_array[0]};
if [ -z ${javac_file} ] ; then
{
echo ">>>>>>> ERROR: could not locate ${JAVAC_LOCATE_PATTERN} (did you remember to do \"make images\"?)";
exit 1;
}
fi
jdk_build_path=$(dirname $(dirname ${javac_file}));
if [ ! -f "build/${JAVAC_LOCATE_PATTERN}" ] ; then
{
echo ">>>>>>> Copying jdk over...";
rsync -a "${jdk_build_path}" "build/";
}
fi
# the following files will be supplied by the Xcode build
rm -rf "build/jdk/lib/server/libjvm.dylib";
rm -rf "build/jdk/lib/server/libjvm.dylib.dSYM";
echo ">>>>>>> DONE";
echo ">>>>>>> Touching ${HOTSPOT_TOUCH_FILE} to force HotspotVM rebuilt";
if [ ! -f ${HOTSPOT_TOUCH_FILE} ] ; then
{
echo ">>>>>>> Cannot find ${HOTSPOT_TOUCH_FILE}";
exit 1;
}
fi
touch ${HOTSPOT_TOUCH_FILE};
echo ">>>>>>> DONE";
echo ">>>>>>> Xcode should be building the HotspotVM now...";

View File

@ -0,0 +1,291 @@
/*
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
public class DiskFile extends LinkedHashMap<Path, DiskFile> implements Comparable<DiskFile> {
// xcode id ex: D50000000000000000000000
private static long xcodeIdCount = 0xF0000001;
private final Path path;
private final boolean directory;
private final String xcodeId;
private final String xcodeId2;
private Iterable<String> compilerFlags;
public DiskFile(String path, boolean directory) {
this(stringToPath(path), directory);
}
private DiskFile(Path path, boolean directory) {
this.path = path;
this.directory = directory;
this.compilerFlags = null;
this.xcodeId = getNextXcodeId();
this.xcodeId2 = getNextXcodeId();
}
private static Path stringToPath(String string) {
if (string != null) {
return new File(string).toPath();
} else {
return null;
}
}
private static Path clipPath(Path path, String clip) {
return clipPath(path.toString(), clip);
}
private static Path clipPath(String path, String clip) {
String subpath = path;
if (path.contains(clip)) {
subpath = clip;
}
int index = path.indexOf(subpath);
return stringToPath(path.substring(index));
}
private String getNextXcodeId() {
String id = "D5FFFFFF" + Long.toHexString(xcodeIdCount).toUpperCase(Locale.ROOT);
xcodeIdCount++;
return id;
}
private String getPath() {
return this.path.toString();
}
public boolean isDirectory() {
return this.directory;
}
public void markAsCompiled(List<String> compilerFlags) {
this.compilerFlags = compilerFlags;
}
private boolean isCompiled() {
return (this.compilerFlags != null);
}
public String getXcodeId() {
return this.xcodeId;
}
public String generatePbxSourcesBuildPhase() {
String string = "";
if (isCompiled()) {
String fileName = getFileName();
string += String.format(" %s /* %s in Sources */,\n", this.xcodeId2, fileName);
} else if (isDirectory()) {
for (Map.Entry<Path, DiskFile> entry : entrySet()) {
DiskFile file = entry.getValue();
string += file.generatePbxSourcesBuildPhase();
}
}
return string;
}
// D5FFFFFFFFFFFFFFF0006506 /* vm_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D5FFFFFFFFFFFFFFF0006505 /* vm_version.cpp */; settings = {COMPILER_FLAGS = HEREHERE; }; };
public String generatePbxBuildFile() {
String string = "";
if (isCompiled()) {
String flagsString = "";
for (String flag : this.compilerFlags) {
flagsString += flag.replace("\"", "\\\\\"") + " ";
}
String fileName = getFileName();
string += String.format(" %s /* %s in Sources */ = {isa = PBXBuildFile; fileRef = %s /* %s */; settings = {COMPILER_FLAGS = \"%s\"; }; };\n", this.xcodeId2, fileName, this.xcodeId, fileName, flagsString);
} else if (isDirectory()) {
for (Map.Entry<Path, DiskFile> entry : entrySet()) {
DiskFile file = entry.getValue();
string += file.generatePbxBuildFile();
}
}
return string;
}
public String generatePbxFileReference(String relativePathToRoot) {
String string = "";
if (!isDirectory()) {
String fileName = getFileName();
String suffix = getFileNameSuffix();
string += String.format(" %s /* %s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = %s%s; name = %s; path = \"%s%s\"; sourceTree = \"<group>\"; };\n", this.xcodeId, fileName, fileName, suffix, fileName, relativePathToRoot, getPath());
} else if (isDirectory()) {
for (Map.Entry<Path, DiskFile> entry : entrySet()) {
DiskFile file = entry.getValue();
string += file.generatePbxFileReference(relativePathToRoot);
}
}
return string;
}
public String generatePbxGroup() {
String string = String.format(" %s /* %s */ = {\n isa = PBXGroup;\n children = (\n", this.xcodeId, getFileName());
Set<DiskFile> sortedSet = new TreeSet<>(values());
for (DiskFile file : sortedSet) {
string += String.format(" %s /* %s */,\n", file.getXcodeId(), file.getFileName());
}
string += String.format(" );\n name = %s;\n sourceTree = \"<group>\";\n };\n", getFileName());
for (DiskFile file : sortedSet) {
if (file.isDirectory()) {
string += file.generatePbxGroup();
}
}
return string;
}
private ArrayList<DiskFile> getFiles(ArrayList<DiskFile> array) {
for (Map.Entry<Path, DiskFile> entry : entrySet()) {
DiskFile file = entry.getValue();
if (file.isDirectory()) {
array.add(file);
array = file.getFiles(array);
} else {
array.add(file);
}
}
return array;
}
public ArrayList<DiskFile> getFiles() {
return getFiles(new ArrayList<>());
}
public String getFilePath() {
return this.path.toString();
}
private String getFileName() {
Path fileName = this.path.getFileName();
if (fileName != null) {
return fileName.toString();
} else {
return this.path.toString();
}
}
private String getFileNameNoSuffix() {
String string;
Path fileName = this.path.getFileName();
if (fileName != null) {
string = fileName.toString();
int index = string.indexOf('.');
if (index >= 0) {
string = string.substring(0, index);
}
} else {
string = this.path.toString();
}
return string;
}
private String getFileNameSuffix() {
String fileName = getFileName();
int index = fileName.indexOf('.');
if (index >= 0) {
return fileName.substring(index);
} else {
return "";
}
}
public DiskFile getChild(String fileName) {
DiskFile child = null;
for (Map.Entry<Path, DiskFile> entry : entrySet()) {
DiskFile file = entry.getValue();
if (file.getFileName().equals(fileName)) {
child = entry.getValue();
break;
} else if (file.isDirectory()) {
child = file.getChild(fileName);
if (child != null) {
break;
}
}
}
return child;
}
private DiskFile getParent(Path path) {
Path pathParent = path.getParent();
DiskFile parent = get(pathParent);
if (parent == null) {
if (this.path.equals(pathParent)) {
parent = this;
} else {
parent = getParent(pathParent).get(pathParent);
}
parent.putIfAbsent(path, new DiskFile(path, true));
}
return parent;
}
public void addFile(Path path, String clip) {
path = clipPath(path, clip);
DiskFile parent = getParent(path);
parent.put(path, new DiskFile(path, false));
}
public void addDirectory(Path path, String clip) {
path = clipPath(path, clip);
DiskFile parent = getParent(path);
parent.putIfAbsent(path, new DiskFile(path, true));
}
@Override
public int compareTo(DiskFile file) {
// ".hpp", then ".inline.hpp", then ".cpp"
int equal = getFileNameNoSuffix().compareTo(file.getFileNameNoSuffix());
if (equal == 0) {
String suffix1 = getFileNameSuffix();
String suffix2 = file.getFileNameSuffix();
if (!suffix1.equals(".inline.hpp") && !suffix2.equals(".inline.hpp")) {
// .hpp before .cpp
equal = -(getFileNameSuffix().compareTo(file.getFileNameSuffix()));
} else if (suffix1.equals(".inline.hpp") && suffix2.equals(".hpp")) {
return 1;
} else if (suffix1.equals(".inline.hpp") && suffix2.equals(".cpp")) {
return -1;
} else if (suffix1.equals(".hpp") && suffix2.equals(".inline.hpp")) {
return -1;
} else if (suffix1.equals(".cpp") && suffix2.equals(".inline.hpp")) {
return 1;
}
}
return equal;
}
}

View File

@ -0,0 +1,754 @@
/*
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystemLoopException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
public final class XcodeProjectMaker {
private static final String JDK_SCRIPT_TOKEN_1 = "configure";
private static final String JDK_SCRIPT_TOKEN_2 = ".jcheck";
private static final String COMPILER_LINE_HEADER = "-I";
private static final String COMPILER_IFRAMEWORK = "-iframework";
private static final String COMPILER_FFRAMEWORK = "-F";
private static final String SRC_HOTSPOT_PATH = "/src/hotspot";
private static final String TEST_HOTSPOT_PATH = "/test/hotspot/gtest";
private static final String ALIAS_JAVA_OLD = "java_old.sh";
private static final String ALIAS_JAVA_NEW = "java_new.sh";
private static final String JDK_BIN_JAVA = "/jdk/bin/java";
private static final String FILE_TOKEN = "\"file\": ";
private static final String COMMAND_TOKEN = "\"command\": ";
private static final String QUOTE_START_TOKEN = "'\\\"";
private static final String QUOTE_END_TOKEN = "\\\"'";
private static final String VERSION = "2.0.0";
private static final String EXCLUDE_PARSE_TOKEN_1 = "gtest";
private static final String TEMPLATE_FRAMEWORK_SEARCH_PATHS = "TEMPLATE_FRAMEWORK_SEARCH_PATHS";
private static final String TEMPLATE_OTHER_CFLAGS = "TEMPLATE_OTHER_CFLAGS";
private static final String TEMPLATE_OTHER_LDFLAGS = "TEMPLATE_OTHER_LDFLAGS";
private static final String TEMPLATE_USER_HEADER_SEARCH_PATHS = "TEMPLATE_USER_HEADER_SEARCH_PATHS";
private static final String TEMPLATE_GROUP_GENSRC = "TEMPLATE_GROUP_GENSRC";
private static final String TEMPLATE_GROUP_SRC = "TEMPLATE_GROUP_SRC";
private static final String TEMPLATE_GROUP_TEST = "TEMPLATE_GROUP_TEST";
private static final String TEMPLATE_GROUPS = "TEMPLATE_GROUPS";
private static final String TEMPLATE_PBXBUILDFILE = "TEMPLATE_PBXBUILDFILE";
private static final String TEMPLATE_PBXFILEREFERENCE = "TEMPLATE_PBXFILEREFERENCE";
private static final String TEMPLATE_PBXSOURCESSBUILDPHASE = "TEMPLATE_PBXSOURCESSBUILDPHASE";
private static final String TEMPLATE_JDK_PATH = "TEMPLATE_JDK_PATH";
private static final String HOTSPOT_PBXPROJ = "hotspot.xcodeproj";
private static final String PBXPROJ = "project.pbxproj";
private static final String XCSAHAREDDATA = "xcshareddata";
private static final String XCSCHEMES = "xcschemes";
private static final String JVM_XCSCHEME = "jvm.xcscheme";
private static final String J2D_XCSCHEME = "runJ2Demo.xcscheme";
private static final String XCDEBUGGER = "xcdebugger";
private static final String XCBKPTLIST = "Breakpoints_v2.xcbkptlist";
private static final String TEMPLATE_PBXPROJ = PBXPROJ + ".template";
private static final String TEMPLATE_JVM_XCSCHEME = JVM_XCSCHEME + ".template";
private static final String TEMPLATE_J2D_XCSCHEME = J2D_XCSCHEME + ".template";
private static final String TEMPLATE_XCBKPTLIST = XCBKPTLIST + ".template";
private static final String[] EXCLUDE_FILES_PREFIX = {"."};
private static final String[] EXCLUDE_FILES_POSTFIX = {".log", ".cmdline"};
private static final String[] COMPILER_FLAGS_INCLUDE = {"-m", "-f", "-D", "-W"};
private static final String[] COMPILER_FLAGS_IS = {"-g", "-Os", "-0"};
private static final String[] COMPILER_FLAGS_EXCLUDE = {"-DTHIS_FILE", "-DGTEST_OS_MAC", "-mmacosx-version-min", "-Werror"}; // "-Werror" causes Xcode to stop compiling
private static final int EXIT4 = -4;
private static final int EXIT5 = -5;
private static final int EXIT6 = -6;
private static final int EXIT7 = -7;
private final HashMap<String, ArrayList<String>> compiledFiles = new HashMap<>();
private final TreeSet<String> compilerFlags = new TreeSet<>();
private List<String> linkerFlags = List.of();
private final TreeSet<String> headerPaths = new TreeSet<>();
private final boolean debugLog;
private String projectMakerDataPath = null;
private String generatedHotspotPath = null;
private String iframework = null;
private String fframework = null;
private DiskFile rootGensrc = new DiskFile("/", true);
private DiskFile rootSrc = new DiskFile("/", true);
private DiskFile rootTest = new DiskFile("/", true);
public XcodeProjectMaker(boolean debugLog) {
this.debugLog = debugLog;
}
public static void main(String[] args) {
String workspaceRoot = args[0];
String outputDir = args[1];
String pathToProjectMakerData = args[2];
String pathToCompileCommands = args[3];
String pathToLinkerOptionsFile = args[4];
String linkerOptionsString = readFile(pathToLinkerOptionsFile);
boolean debugLog = args.length > 5 && args[5].equals("-d");
File xcodeFolder = new File(outputDir);
xcodeFolder.mkdirs();
String workspaceRootPathFromOutputDir = findRelativePathToWorkspaceRoot(outputDir);
if (debugLog) {
System.out.println();
System.out.println("Version " + VERSION);
System.out.println();
System.out.println(" Path to workspace root is \"" + workspaceRoot + "\"");
System.out.println("Path to compile commands file is \"" + pathToCompileCommands + "\"");
System.out.println(" Xcode project will be placed in \"" + outputDir + "\"");
System.out.println();
}
XcodeProjectMaker maker = new XcodeProjectMaker(debugLog);
maker.parseHotspotCompileCommands(pathToCompileCommands);
maker.linkerFlags = List.of(linkerOptionsString.split(" "));
maker.projectMakerDataPath = pathToProjectMakerData;
maker.printLogDetails();
maker.prepareFiles(workspaceRoot);
maker.makeXcodeProj(outputDir, workspaceRootPathFromOutputDir);
String pathToBuild = getFileParent(outputDir);
maker.makeAliases(outputDir, pathToBuild);
System.out.println();
System.out.println("The Xcode project for hotspot was succesfully created");
System.out.println("It can be found in '" + outputDir + "/" + HOTSPOT_PBXPROJ + "'");
System.out.println();
}
// find a path to what looks like jdk
private static String findRelativePathToWorkspaceRoot(String root) {
String pathToWorkspaceRoot = null;
String path = root;
boolean found1 = false;
boolean found2 = false;
while (!found1 && !found2) {
File folder = new File(path);
File[] files = folder.listFiles();
for (File file : files) {
String fileName = file.toPath().getFileName().toString();
if (fileName.equals(JDK_SCRIPT_TOKEN_1)) {
found1 = true;
}
if (fileName.equals(JDK_SCRIPT_TOKEN_2)) {
found2 = true;
}
if (found1 && found2) {
break;
}
}
if (!found1 && !found2) {
path = Paths.get(path).getParent().toString();
if (pathToWorkspaceRoot == null) {
pathToWorkspaceRoot = "..";
} else {
pathToWorkspaceRoot += "/..";
}
}
}
return pathToWorkspaceRoot;
}
private static String readFile(File file) {
return readFile(file.toPath());
}
private static String readFile(String path) {
return readFile(Paths.get(path));
}
private static String readFile(Path path) {
try {
return Files.readString(path);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static void writeFile(File file, String string) {
writeFile(file.toPath(), string);
}
private static void writeFile(Path path, String string) {
try {
Files.writeString(path, string);
} catch (IOException e) {
e.printStackTrace();
System.exit(EXIT4);
}
}
private static boolean excludeFile(Path path) {
return excludeFile(path.toString());
}
private static boolean excludeFile(String string) {
return excludeFile(string, null);
}
private static boolean excludeFile(String string, String exclude) {
if (exclude != null) {
if (contains(string, exclude)) {
return true;
}
}
for (String excludeFilesPrefix : EXCLUDE_FILES_PREFIX) {
if (string.startsWith(excludeFilesPrefix)) {
return true;
}
}
for (String excludeFilesPostfix : EXCLUDE_FILES_POSTFIX) {
if (string.endsWith(excludeFilesPostfix)) {
return true;
}
}
return false;
}
private static boolean isExcludeCompilerFlag(String string) {
boolean flag = false;
for (String exclude : COMPILER_FLAGS_EXCLUDE) {
if (string.contains(exclude)) {
flag = true;
break;
}
}
return flag;
}
private static boolean isCompilerFlag(String string) {
boolean flag = false;
for (String include : COMPILER_FLAGS_INCLUDE) {
if (string.startsWith(include)) {
flag = true;
break;
}
}
for (String is : COMPILER_FLAGS_IS) {
if (string.equals(is)) {
flag = true;
break;
}
}
if (isExcludeCompilerFlag(string)) {
flag = false;
}
return flag;
}
private static String strip(String string) {
return string.substring(2, string.length() - 1);
}
private static String strip(String string, String token) {
int start = string.indexOf(token);
int end = start + token.length();
return strip(string.substring(end));
}
private static boolean contains(String string, String token) {
return ((string.length() >= token.length()) && (string.contains(token)));
}
private static String getFileParent(String path) {
return Paths.get(path).getParent().toString();
}
private static String extractPath(String string, String from, String to) {
String result = null;
String[] tokens = string.split("/");
int i = 0;
for (; i < tokens.length; i++) {
if (tokens[i].equals(from)) {
result = "";
break;
}
}
for (; i < tokens.length; i++) {
result += "/" + tokens[i];
if (tokens[i].equals(to)) {
break;
}
}
return result;
}
private void extractCommonCompilerFlags() {
// heuristic, find average count of number of flags used by each compiled file
int countFiles = 0;
int countFlags = 0;
for (Map.Entry<String, ArrayList<String>> entry : this.compiledFiles.entrySet()) {
countFiles++;
List<String> flags = entry.getValue();
countFlags += flags.size();
}
// when finding common flags, only consider files with this many flags
int flagCutoff = (countFlags / countFiles) / 2;
// collect all flags
for (Map.Entry<String, ArrayList<String>> entry : this.compiledFiles.entrySet()) {
List<String> flags = entry.getValue();
if (flags.size() > flagCutoff) {
this.compilerFlags.addAll(flags);
}
}
// find flags to remove
Set<String> removeFlags = new TreeSet<>();
for (Map.Entry<String, ArrayList<String>> entry : this.compiledFiles.entrySet()) {
List<String> flags = entry.getValue();
if (flags.size() > flagCutoff) {
for (String common : this.compilerFlags) {
if (!flags.contains(common)) {
removeFlags.add(common);
}
}
}
}
// leave only common flags
for (String flag : removeFlags) {
this.compilerFlags.remove(flag);
}
// remove common flags from each compiler file, leaving only the unique ones
for (Map.Entry<String, ArrayList<String>> entry : this.compiledFiles.entrySet()) {
List<String> flags = entry.getValue();
if (flags.size() > flagCutoff) {
for (String common : this.compilerFlags) {
flags.remove(common);
}
}
}
}
private void extractCompilerFlags(String line) {
boolean verboseCompilerTokens = false;
String file = null;
ArrayList<String> flags = null;
String[] commands = line.split(",");
for (String command : commands) {
if (contains(command, FILE_TOKEN)) {
file = strip(command, FILE_TOKEN);
//verbose_compiler_tokens = Contains(file, "vm_version.cpp");
} else if (contains(command, COMMAND_TOKEN)) {
String tokens = strip(command, COMMAND_TOKEN);
String[] arguments = tokens.split(" ");
if (arguments.length >= 3) {
flags = new ArrayList<>();
for (int a = 2; a < arguments.length; a++) {
String argument = arguments[a];
if (isCompilerFlag(argument)) {
// catch argument like -DVMTYPE=\"Minimal\"
if (contains(argument, "\\\\\\\"") && argument.endsWith("\\\\\\\"")) {
// TODO: more robust fix needed here
argument = argument.replace("\\", "");
argument = argument.replaceFirst("\"", "~.~"); // temp token ~.~
argument = argument.replace("\"", "\\\"'");
argument = argument.replace("~.~", "'\\\"");
}
// argument like -DHOTSPOT_VM_DISTRO='\"Java HotSpot(TM)\"'
// gets split up, so reconstruct as single string
if (contains(argument, QUOTE_START_TOKEN) && !argument.endsWith(QUOTE_END_TOKEN)) {
String fullArgument = argument;
do {
++a;
argument = arguments[a];
fullArgument = fullArgument + " " + argument;
} while (!argument.endsWith(QUOTE_END_TOKEN));
argument = fullArgument;
}
flags.add(argument);
if (verboseCompilerTokens) {
System.out.println(" FOUND COMPILER FLAG: " + argument);
}
} else if (argument.startsWith(COMPILER_LINE_HEADER)) {
this.headerPaths.add(argument.substring(2));
} else if (argument.equals(COMPILER_IFRAMEWORK)) {
if (iframework == null) {
++a;
this.iframework = arguments[a]; // gets the value, so skip it for the next loop
}
} else if (argument.equals(COMPILER_FFRAMEWORK)) {
if (fframework == null) {
++a;
this.fframework = arguments[a]; // gets the value, so skip it for the next loop
}
}
}
}
}
}
if ((file != null) && (flags != null)) {
this.compiledFiles.put(file, flags);
} else {
System.err.println(" WARNING: extractCompilerFlags returns file:" + file + ", flags:" + flags);
}
if (verboseCompilerTokens) {
System.exit(0);
}
}
public void parseHotspotCompileCommands(String path) {
String content = readFile(path);
String[] parts = content.split("\\{"); // }
int found = 0;
for (String line : parts) {
if (!contains(line, EXCLUDE_PARSE_TOKEN_1) && !line.startsWith("[")) {
extractCompilerFlags(line);
found++;
}
}
if (debugLog) {
System.out.println("Found total of " + found + " files that make up the libjvm.dylib");
}
extractCommonCompilerFlags();
// figure out "gensrc" folder
// from: "/Users/gerard/Desktop/jdk_test/jdk10/build/macosx-x86_64-normal-server-fastdebug/hotspot/variant-server/gensrc/adfiles/ad_x86_clone.cpp"
// to: "/build/macosx-x86_64-normal-server-fastdebug/hotspot/variant-server/gensrc"
for (Map.Entry<String, ArrayList<String>> entry : this.compiledFiles.entrySet()) {
String file = entry.getKey();
if (file.contains("gensrc")) {
this.generatedHotspotPath = extractPath(file, "build", "gensrc");
//generatedHotspotPath = "/build/macosx-x64/hotspot/variant-server/gensrc";
//generatedHotspotPath = "/build/macosx-x86_64-normal-server-fastdebug/hotspot/variant-server/gensrc";
}
}
}
// https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/essential/io/examples/Copy.java
private DiskFile getHotspotFiles(DiskFile root, String workspaceRoot, String hotspotPath) {
File file = new File(workspaceRoot + "/" + hotspotPath);
if (!file.exists()) {
return null;
}
try {
final Path rootDir = Paths.get(workspaceRoot + hotspotPath);
Files.walkFileTree(rootDir, new HotspotFileVisitor(root, hotspotPath));
} catch (IOException ex) {
System.err.println("ex: " + ex);
}
return root;
}
public void prepareFiles(String workspaceRoot) {
this.rootGensrc = getHotspotFiles(this.rootGensrc, workspaceRoot, this.generatedHotspotPath);
this.rootSrc = getHotspotFiles(this.rootSrc, workspaceRoot, SRC_HOTSPOT_PATH);
this.rootTest = getHotspotFiles(this.rootTest, workspaceRoot, TEST_HOTSPOT_PATH);
// make a copy of files from the log
Set<String> logFiles = new TreeSet<>(this.compiledFiles.keySet());
int totalMarkedFiles = 0;
DiskFile[] roots = { this.rootGensrc, this.rootSrc };
for (DiskFile root : roots) {
List<DiskFile> diskFiles = root.getFiles();
for (DiskFile diskFile : diskFiles) {
if (!diskFile.isDirectory()) {
String logFileProcessed = null;
String diskFilePath = diskFile.getFilePath();
for (String logFilePath : logFiles) {
if (contains(logFilePath, diskFilePath)) {
totalMarkedFiles++;
logFileProcessed = logFilePath;
// mark the file as needing compilation
diskFile.markAsCompiled(this.compiledFiles.get(logFilePath));
// break early if found
break;
}
}
if (logFileProcessed != null) {
// remove the file, so we don't have to search through it again
logFiles.remove(logFileProcessed);
}
}
}
}
if (this.compiledFiles.size() != totalMarkedFiles) {
System.err.println("\nError: was expecting to compile " + this.compiledFiles.size() + " files, but marked " + totalMarkedFiles);
for (String file : logFiles) {
System.err.println("file: " + file);
}
System.exit(EXIT5);
}
if (!logFiles.isEmpty()) {
System.err.println("\nError: unprocessed files left over:");
for (String logFile : logFiles) {
System.err.println(" " + logFile);
}
System.exit(EXIT6);
}
}
public void printLogDetails() {
if (!debugLog) return;
System.out.println("\nFound " + this.compilerFlags.size() + " common compiler flags:");
for (String flag : this.compilerFlags) {
System.out.println(" " + flag);
}
System.out.println("\nList of compiled files (each one uses common compiler flags plus extra ones as specified):");
int count = 1;
for (Map.Entry<String, ArrayList<String>> entry : this.compiledFiles.entrySet()) {
String file = entry.getKey();
System.out.format("%4d: %s\n", (count), file);
count++;
List<String> flags = entry.getValue();
for (String flag : flags) {
System.out.println(" " + flag);
}
}
System.out.println("\nFound " + this.linkerFlags.size() + " linker flags:");
for (String flag : this.linkerFlags) {
System.out.println(" " + flag);
}
System.out.println("\nFound " + this.headerPaths.size() + " header paths:");
for (String header : this.headerPaths) {
System.out.println(" " + header);
}
System.out.println("\nFrameworks:");
System.out.println(" -iframework " + iframework);
System.out.println(" -f " + fframework);
}
private String makeProjectPbxproj(String workspaceRootPathFromOutputDir, String string) {
String cFlags = "";
for (String flag : this.compilerFlags) {
cFlags += " \"" + flag.replace("\"", "\\\\\"") + "\",\n";
}
cFlags = cFlags.substring(0, cFlags.length() - 2);
string = string.replaceFirst(TEMPLATE_OTHER_CFLAGS, cFlags);
String ldFlags = "";
for (String flag : this.linkerFlags) {
ldFlags += " \"" + flag + "\",\n";
}
ldFlags = ldFlags.substring(0, ldFlags.length() - 2);
string = string.replaceFirst(TEMPLATE_OTHER_LDFLAGS, ldFlags);
String headerPaths = "";
for (String header : this.headerPaths) {
headerPaths += " \"" + header + "\",\n";
}
headerPaths = headerPaths.substring(0, headerPaths.length() - 2);
string = string.replaceFirst(TEMPLATE_USER_HEADER_SEARCH_PATHS, headerPaths);
String frameworkPaths = "";
if (fframework != null) {
frameworkPaths += " \"" + fframework + "\"\n";
}
string = string.replaceFirst(TEMPLATE_FRAMEWORK_SEARCH_PATHS, frameworkPaths);
DiskFile gensrcFile = this.rootGensrc.getChild("gensrc");
string = string.replaceFirst(TEMPLATE_GROUP_GENSRC, " " + gensrcFile.getXcodeId());
DiskFile srcFile = this.rootSrc.getChild("src");
string = string.replaceFirst(TEMPLATE_GROUP_SRC, " " + srcFile.getXcodeId());
DiskFile testFile = this.rootTest.getChild("test");
string = string.replaceFirst(TEMPLATE_GROUP_TEST, " " + testFile.getXcodeId());
String gensrcGroups = gensrcFile.generatePbxGroup();
String srcGroups = srcFile.generatePbxGroup();
String testGroups = testFile.generatePbxGroup();
string = string.replaceFirst(TEMPLATE_GROUPS, gensrcGroups + srcGroups + testGroups);
String gensrcFiles = gensrcFile.generatePbxFileReference(workspaceRootPathFromOutputDir);
String srcFiles = srcFile.generatePbxFileReference(workspaceRootPathFromOutputDir);
String testFiles = testFile.generatePbxFileReference(workspaceRootPathFromOutputDir);
string = string.replaceFirst(TEMPLATE_PBXFILEREFERENCE, gensrcFiles + srcFiles + testFiles);
String gensrcCompiled = gensrcFile.generatePbxBuildFile();
String compiled = srcFile.generatePbxBuildFile();
string = string.replaceFirst(TEMPLATE_PBXBUILDFILE, gensrcCompiled + compiled);
String gensrcBuilt = gensrcFile.generatePbxSourcesBuildPhase();
String built = srcFile.generatePbxSourcesBuildPhase();
string = string.replaceFirst(TEMPLATE_PBXSOURCESSBUILDPHASE, gensrcBuilt + built);
return string;
}
private String makeTemplateXcscheme(String outputDir, String string) {
string = string.replaceAll(TEMPLATE_JDK_PATH, outputDir);
return string;
}
public void makeXcodeProj(String outputDir, String workspaceRootPathFromOutputDir) {
/*
jvm.xcodeproj <-- folder
project.pbxproj <-- file
xcshareddata <-- folder
xcschemes <-- folder
jvm.xcscheme <-- file
xcdebugger <-- folder
Breakpoints_v2.xcbkptlist <-- file
*/
File xcodeDir = new File(outputDir);
File jvmXcodeprojDir = new File(xcodeDir, HOTSPOT_PBXPROJ);
File projectPbxprojFile = new File(jvmXcodeprojDir, PBXPROJ);
File xcshareddataDir = new File(jvmXcodeprojDir, XCSAHAREDDATA);
File xcschemesDir = new File(xcshareddataDir, XCSCHEMES);
File jvmXcschemeFile = new File(xcschemesDir, JVM_XCSCHEME);
File j2DemoXcschemeFile = new File(xcschemesDir, J2D_XCSCHEME);
File xcdebuggerDir = new File(xcshareddataDir, XCDEBUGGER);
File jBreakpointsV2XcbkptlistFile = new File(xcdebuggerDir, XCBKPTLIST);
if (xcodeDir.exists()) {
xcodeDir.delete();
}
jvmXcodeprojDir.mkdirs();
xcshareddataDir.mkdirs();
xcschemesDir.mkdirs();
xcdebuggerDir.mkdirs();
File dataDir = new File(projectMakerDataPath);
File templateProjectPbxprojFile = new File(dataDir, TEMPLATE_PBXPROJ);
File templateJvmXcschemeFile = new File(dataDir, TEMPLATE_JVM_XCSCHEME);
File templateJ2DemoXcschemeFile = new File(dataDir, TEMPLATE_J2D_XCSCHEME);
File templateJBreakpointsV2XcbkptlistFile = new File(dataDir, TEMPLATE_XCBKPTLIST);
String projectPbxprojString = readFile(templateProjectPbxprojFile);
String jvmXcschemeString = readFile(templateJvmXcschemeFile);
String j2DemoXcschemeString = readFile(templateJ2DemoXcschemeFile);
String jBreakpointsV2XcbkptlistString = readFile(templateJBreakpointsV2XcbkptlistFile);
writeFile(projectPbxprojFile, makeProjectPbxproj(workspaceRootPathFromOutputDir, projectPbxprojString));
writeFile(jvmXcschemeFile, makeTemplateXcscheme(outputDir, jvmXcschemeString));
writeFile(j2DemoXcschemeFile, makeTemplateXcscheme(outputDir, j2DemoXcschemeString));
writeFile(jBreakpointsV2XcbkptlistFile, jBreakpointsV2XcbkptlistString);
}
public void makeAliases(String outputDir, String pathToBuild) {
File xcodeDir = new File(outputDir);
File jdkOldSh = new File(xcodeDir, ALIAS_JAVA_OLD);
File jdkNewSh = new File(xcodeDir, ALIAS_JAVA_NEW);
writeFile(jdkOldSh, "#!/bin/bash\n" + pathToBuild + JDK_BIN_JAVA + " $@");
writeFile(jdkNewSh, "#!/bin/bash\n" + outputDir + "/build" + JDK_BIN_JAVA + " $@");
try {
Set<PosixFilePermission> permissions = new HashSet<>();
permissions.add(PosixFilePermission.OWNER_READ);
permissions.add(PosixFilePermission.OWNER_WRITE);
permissions.add(PosixFilePermission.OWNER_EXECUTE);
permissions.add(PosixFilePermission.GROUP_READ);
permissions.add(PosixFilePermission.OTHERS_READ);
Files.setPosixFilePermissions(jdkOldSh.toPath(), permissions);
Files.setPosixFilePermissions(jdkNewSh.toPath(), permissions);
} catch (IOException ex) {
System.err.println("Warning: unable to change file permissions");
System.err.println(ex);
}
}
private static class HotspotFileVisitor implements FileVisitor<Path> {
private final DiskFile root;
private final String hotspotPath;
public HotspotFileVisitor(DiskFile root, String hotspotPath) {
this.root = root;
this.hotspotPath = hotspotPath;
}
@Override
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs) {
if (excludeFile(path)) {
return FileVisitResult.SKIP_SUBTREE;
} else {
// consider folders based on their names
Path file = path.getFileName();
if (!excludeFile(file)) {
root.addDirectory(path, hotspotPath);
return FileVisitResult.CONTINUE;
} else {
// skip folders with names beginning with ".", etc
return FileVisitResult.SKIP_SUBTREE;
}
}
}
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
Path file = path.getFileName();
if (!excludeFile(file)) {
//System.err.println(path.toString());
root.addFile(path, hotspotPath);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path path, IOException exc) {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path path, IOException exc) {
if (exc instanceof FileSystemLoopException) {
System.err.println("cycle detected: " + path);
} else {
System.err.format("Unable to process: %s: %s\n", path, exc);
}
return FileVisitResult.CONTINUE;
}
}
}

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -51,27 +51,25 @@ endif
ifeq ($(call isTargetOs, windows)+$(CREATING_BUILDJDK), true+false)
# Chmod to avoid permission issues if bundles are unpacked on unix platforms.
define copy-and-chmod
$(install-file)
$(CHMOD) a+rx $@
endef
# Use separate macro calls in case the source files are not in the same
# directory.
$(eval $(call SetupCopyFiles,COPY_MSVCR, \
$(eval $(call SetupCopyFiles, COPY_MSVCR, \
DEST := $(LIB_DST_DIR), \
FILES := $(MSVCR_DLL), \
MACRO := copy-and-chmod))
MACRO := copy-and-chmod-executable, \
))
$(eval $(call SetupCopyFiles,COPY_VCRUNTIME_1, \
$(eval $(call SetupCopyFiles, COPY_VCRUNTIME_1, \
DEST := $(LIB_DST_DIR), \
FILES := $(VCRUNTIME_1_DLL), \
MACRO := copy-and-chmod))
MACRO := copy-and-chmod-executable, \
))
$(eval $(call SetupCopyFiles,COPY_MSVCP, \
$(eval $(call SetupCopyFiles, COPY_MSVCP, \
DEST := $(LIB_DST_DIR), \
FILES := $(MSVCP_DLL), \
MACRO := copy-and-chmod))
MACRO := copy-and-chmod-executable, \
))
TARGETS += $(COPY_MSVCR) $(COPY_VCRUNTIME_1) $(COPY_MSVCP)
@ -80,7 +78,7 @@ ifeq ($(call isTargetOs, windows)+$(CREATING_BUILDJDK), true+false)
DEST := $(LIB_DST_DIR), \
SRC := $(UCRT_DLL_DIR), \
FILES := $(wildcard $(UCRT_DLL_DIR)/*.dll), \
MACRO := copy-and-chmod, \
MACRO := copy-and-chmod-executable, \
))
TARGETS += $(COPY_UCRT_DLLS)