Commit d9d37e55 authored by Anton Bikineev's avatar Anton Bikineev Committed by Commit Bot

cppgc: mirror: Support cmake targets for tests and sample

Bug: v8:10724
Change-Id: Ia0b6d6d25e6b9d7b44b4dfa94705e9cd5103cc8e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2316303Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69094}
parent 721dac7d
......@@ -8,6 +8,7 @@ import sys
import lark
import argparse
from contextlib import suppress
from collections import namedtuple
from datetime import datetime
# GN grammar from https://gn.googlesource.com/gn/+/master/src/gn/parser.cc.
......@@ -64,8 +65,6 @@ GN_GRAMMAR = """
%ignore COMMENT
"""
FILTERED_TARGETS = ('v8_libbase', 'v8_cppgc_shared', 'cppgc_base')
V8_TARGET_TYPES = (
'v8_component',
'v8_source_set',
......@@ -211,13 +210,23 @@ class V8GNTransformer(object):
}
TARGETS = {
'v8_libbase': 'lib',
'v8_cppgc_shared': 'lib',
'cppgc_base': 'lib',
'cppgc_standalone': 'sample',
'cppgc_unittests_sources': 'tests',
'cppgc_unittests': 'tests',
}
class CMakeBuilder(object):
"""
Builder that produces the main CMakeLists.txt.
"""
def __init__(self):
self.result = []
self.source_sets = []
self.source_sets = {}
def BuildPrologue(self):
self.result.append(f"""
......@@ -225,11 +234,14 @@ class CMakeBuilder(object):
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This file is automatically generated by {__file__}.
# This file is automatically generated by {__file__}. Do NOT edit it.
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.11)
project(cppgc CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
option(CPPGC_ENABLE_OBJECT_NAMES "Enable object names in cppgc for debug purposes" OFF)
option(CPPGC_ENABLE_CAGED_HEAP "Enable heap reservation of size 4GB, only possible for 64bit archs" OFF)
option(CPPGC_ENABLE_YOUNG_GENERATION "Enable young generation in cppgc" OFF)
......@@ -262,39 +274,48 @@ endif()
if(CPPGC_64_BITS)
# Always enable caged heap for 64bits archs.
set(CPPGC_ENABLE_CAGED_HEAP ON FORCE)
set(CPPGC_ENABLE_CAGED_HEAP ON CACHE BOOL "Enable caged heap for 64bit" FORCE)
endif()
if(CPPGC_ENABLE_YOUNG_GENERATION AND NOT CPPGC_ENABLE_CAGED_HEAP)
message(FATAL_ERROR "Young generation is only supported for caged heap configuration")
endif()
""")
def BuildEpilogue(self):
self.result.append(f"""
# Main target.
add_library(cppgc {' '.join(self.source_sets)})
target_include_directories(cppgc PRIVATE "${{CMAKE_SOURCE_DIR}}"
PRIVATE "${{CMAKE_SOURCE_DIR}}/include")
if(NOT CPPGC_64_BITS)
if(NOT MSVC)
set_target_properties(cppgc PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
set(CMAKE_CXX_FLAGS "${{CMAKE_CXX_FLAGS}} -m32")
set(CMAKE_C_FLAGS "${{CMAKE_C_FLAGS}} -m32")
set(CMAKE_EXE_LINKER_FLAGS "${{CMAKE_EXE_LINKER_FLAGS}} -m32")
set(CMAKE_SHARED_LINKER_FLAGS "${{CMAKE_SHARED_LINKER_FLAGS}} -m32")
set(CMAKE_MODULE_LINKER_FLAGS "${{CMAKE_MODULE_LINKER_FLAGS}} -m32")
endif()
endif()
if(CPPGC_ENABLE_OBJECT_NAMES)
target_compile_definitions(cppgc PRIVATE "-DCPPGC_SUPPORTS_OBJECT_NAMES")
endif()
if(CPPGC_ENABLE_CAGED_HEAP)
target_compile_definitions(cppgc PRIVATE "-DCPPGC_CAGED_HEAP")
endif()
if(CPPGC_ENABLE_YOUNG_GENERATION)
target_compile_definitions(cppgc PRIVATE "-DCPPGC_YOUNG_GENERATION")
find_package(Threads REQUIRED)
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY "https://chromium.googlesource.com/external/github.com/google/googletest.git"
GIT_TAG "4fe018038f87675c083d0cfb6a6b57c274fb1753"
SOURCE_DIR "${{CMAKE_BINARY_DIR}}/third_party/googletest/src"
)
FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
FetchContent_Populate(googletest)
message("Fetched googletest into ${{googletest_SOURCE_DIR}}")
add_subdirectory(${{googletest_SOURCE_DIR}} ${{googletest_BINARY_DIR}} EXCLUDE_FROM_ALL)
include_directories("${{CMAKE_BINARY_DIR}}")
endif()
""")
def BuildEpilogue(self):
self.result.extend(
self._GenTargetString(target, sets)
for target, sets in self.source_sets.items())
self.result.append("\ninstall(TARGETS cppgc)")
def BuildTarget(self, target_type, target, rules):
# Don't generate CMake targets yet, defer it to build_epilogue.
comment = f"""
......@@ -303,16 +324,20 @@ endif()
#==============================================================================="""
self.result.append(comment)
self.result.extend(rules)
self.source_sets.append('${' + self._SourceVar(target) + '}')
self.source_sets.setdefault(
TARGETS[target], []).append('${' + self._SourceVar(target) + '}')
def BuildSourcesList(self, target, sources):
return f'set({self._SourceVar(target)} {" ".join(sources)})'
sources = self._ExpandSources(target, sources)
return f'set({self._SourceVar(target)} {sources})'
def BuildAppendSources(self, target, sources):
return f'list(APPEND {self._SourceVar(target)} {" ".join(sources)})'
sources = self._ExpandSources(target, sources)
return f'list(APPEND {self._SourceVar(target)} {sources})'
def BuildRemoveSources(self, target, sources):
return f'list(REMOVE_ITEM {self._SourceVar(target)} {" ".join(sources)})'
sources = self._ExpandSources(target, sources)
return f'list(REMOVE_ITEM {self._SourceVar(target)} {sources})'
def BuildCondition(self, cond, then_stmts):
return f"""
......@@ -372,6 +397,52 @@ else{else_cond}
def GetResult(self):
return '\n'.join(self.result)
@staticmethod
def _GenTargetString(target_type, source_sets):
Target = namedtuple('Target', 'name cmake deps desc')
CMAKE_TARGETS = {
'lib':
Target(name='cppgc',
cmake='add_library',
deps=['Threads::Threads'],
desc='Main library'),
'sample':
Target(name='cppgc_sample',
cmake='add_executable',
deps=['cppgc'],
desc='Example'),
'tests':
Target(name='cppgc_unittests',
cmake='add_executable',
deps=['cppgc', 'gtest', 'gmock'],
desc='Unittests')
}
target = CMAKE_TARGETS[target_type]
return f"""
# {target.desc} target.
{target.cmake}({target.name} {' '.join(source_sets)})
{'target_link_libraries(' + target.name + ' ' + ' '.join(target.deps) + ')' if target.deps else ''}
target_include_directories({target.name} PRIVATE "${{CMAKE_SOURCE_DIR}}"
PRIVATE "${{CMAKE_SOURCE_DIR}}/include")
if(CPPGC_ENABLE_OBJECT_NAMES)
target_compile_definitions({target.name} PRIVATE "-DCPPGC_SUPPORTS_OBJECT_NAMES")
endif()
if(CPPGC_ENABLE_CAGED_HEAP)
target_compile_definitions({target.name} PRIVATE "-DCPPGC_CAGED_HEAP")
endif()
if(CPPGC_ENABLE_YOUNG_GENERATION)
target_compile_definitions({target.name} PRIVATE "-DCPPGC_YOUNG_GENERATION")
endif()"""
@staticmethod
def _ExpandSources(target, sources):
if TARGETS[target] == 'tests':
sources = ['\"test/unittests/' + s[1:] for s in sources]
return ' '.join(sources)
@staticmethod
def _SourceVar(target):
return CMakeBuilder._CMakeVar(target) + '_SOURCES'
......@@ -410,14 +481,18 @@ def ParseGN(contents):
return parser.parse(contents)
def GenCMake(infile, outfile):
data = None
with open(infile, 'r') as ifile:
data = ifile.read()
cmake_builder = CMakeBuilder()
tree = ParseGN(data)
V8GNTransformer(cmake_builder, FILTERED_TARGETS).Traverse(tree)
result = FormatCMake(cmake_builder.GetResult())
def ParseGNFile(filename):
with open(filename, 'r') as file:
contents = file.read()
return ParseGN(contents)
def GenCMake(main_gn, test_gn, outfile):
tree = ParseGNFile(main_gn)
tree.children.extend(ParseGNFile(test_gn).children)
builder = CMakeBuilder()
V8GNTransformer(builder, TARGETS.keys()).Traverse(tree)
result = FormatCMake(builder.GetResult())
SaveContents(result, outfile)
......@@ -426,13 +501,16 @@ def Main():
description=
'Generate CMake from the main GN file for targets needed to build CppGC.'
)
arg_parser.add_argument('-o', help='Output filename', default='-')
arg_parser.add_argument('infile',
help='Input filename',
arg_parser.add_argument('--out', help='output CMake filename', default='-')
arg_parser.add_argument('--main-gn',
help='main BUILD.gn input file',
default='BUILD.gn')
arg_parser.add_argument('--test-gn',
help='unittest BUILD.gn input file',
default='test/unittests/BUILD.gn')
args = arg_parser.parse_args()
GenCMake(args.infile, args.o)
GenCMake(args.main_gn, args.test_gn, args.out)
return 0
......
......@@ -20,7 +20,7 @@ class CMakeMockBuilder(CMakeBuilder):
class CMakeGenerationTest(unittest.TestCase):
TARGET = 'test_target'
TARGET = 'cppgc_base'
CMAKE_TARGET_SOURCES = TARGET.upper() + '_SOURCES'
def test_source_assignment(self):
......
#!/bin/sh
#
# Copyright 2020 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
sourcedir=$(cd "$(dirname "$0")"; pwd -P)
rootdir=$sourcedir/../../
testdir=$rootdir/test/unittests/
maingn=$rootdir/BUILD.gn
testgn=$testdir/BUILD.gn
function fail {
echo -e "\033[0;31m$1\033[0m" > /dev/stderr
exit 1
}
function cleanup {
rm $cmakelists
if [[ -d "$tempdir" ]]; then
rm -rf $tempdir
fi
}
trap "exit 1" HUP INT PIPE QUIT TERM
trap cleanup EXIT
if [[ ! -f "$maingn" || ! -f "$testgn" ]]; then
fail "Expected GN files are not present"
fi
cmakelists=$rootdir/CMakeLists.txt
# Generate CMakeLists.txt in the root project directory.
$sourcedir/gen_cmake.py --out=$cmakelists --main-gn=$maingn --test-gn=$testgn
if [ $? -ne 0 ]; then
fail "CMakeLists.txt generation has failed"
fi
# Create a temporary build directory.
tempdir=$(mktemp -d)
if [[ ! "$tempdir" || ! -d "$tempdir" ]]; then
fail "Failed to create temporary dir"
fi
# Configure project with cmake.
cd $tempdir
cmake -GNinja $rootdir || fail "Failed to execute cmake"
# Build all targets.
ninja cppgc || fail "Failed to build cppgc"
ninja cppgc_sample || fail "Failed to build sample"
ninja cppgc_unittests || fail "Failed to build unittests"
# Run unittests.
./cppgc_unittests || fail "Failed to run unittests"
echo -e "\033[0;32mThe test has succesfully passed\033[0m"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment