aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/cmake/interpreter.py43
-rw-r--r--mesonbuild/interpreter.py11
-rw-r--r--test cases/cmake/4 object library/main.cpp9
-rw-r--r--test cases/cmake/4 object library/meson.build14
-rw-r--r--test cases/cmake/4 object library/subprojects/cmObjLib/CMakeLists.txt10
-rw-r--r--test cases/cmake/4 object library/subprojects/cmObjLib/libA.cpp5
-rw-r--r--test cases/cmake/4 object library/subprojects/cmObjLib/libA.hpp5
-rw-r--r--test cases/cmake/4 object library/subprojects/cmObjLib/libB.cpp6
-rw-r--r--test cases/cmake/4 object library/subprojects/cmObjLib/libB.hpp5
9 files changed, 101 insertions, 7 deletions
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
index ae42ae7..7073e94 100644
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -20,11 +20,11 @@ from .client import CMakeClient, RequestCMakeInputs, RequestConfigure, RequestCo
from .. import mlog
from ..build import Build
from ..environment import Environment
-from ..mparser import Token, BaseNode, CodeBlockNode, FunctionNode, ArrayNode, ArgumentNode, AssignmentNode, BooleanNode, StringNode, IdNode
+from ..mparser import Token, BaseNode, CodeBlockNode, FunctionNode, ArrayNode, ArgumentNode, AssignmentNode, BooleanNode, StringNode, IdNode, MethodNode
from ..backend.backends import Backend
from ..dependencies.base import CMakeDependency, ExternalProgram
from subprocess import Popen, PIPE, STDOUT
-from typing import Dict
+from typing import Dict, List
import os, re
CMAKE_BACKEND_GENERATOR_MAP = {
@@ -50,6 +50,7 @@ CMAKE_TGT_TYPE_MAP = {
'MODULE_LIBRARY': 'shared_module',
'SHARED_LIBRARY': 'shared_library',
'EXECUTABLE': 'executable',
+ 'OBJECT_LIBRARY': 'static_library',
}
class ConverterTarget:
@@ -75,6 +76,7 @@ class ConverterTarget:
self.generated = []
self.includes = []
self.link_with = []
+ self.object_libs = []
self.compile_opts = {}
self.pie = False
@@ -160,6 +162,17 @@ class ConverterTarget:
if os.path.commonpath([self.install_dir, install_prefix]) == install_prefix:
self.install_dir = os.path.relpath(self.install_dir, install_prefix)
+ def process_object_libs(self, obj_target_list: List['ConverterTarget']):
+ # Try to detect the object library(s) from the generated input sources
+ temp = [os.path.basename(x) for x in self.generated if x.endswith('.o')]
+ self.generated = [x for x in self.generated if not x.endswith('.o')]
+ for i in obj_target_list:
+ out_objects = [os.path.basename(x + '.o') for x in i.sources + i.generated]
+ for j in out_objects:
+ if j in temp:
+ self.object_libs += [i]
+ break
+
def meson_func(self) -> str:
return CMAKE_TGT_TYPE_MAP.get(self.type.upper())
@@ -171,6 +184,7 @@ class ConverterTarget:
mlog.log(' -- install_dir: ', mlog.bold(self.install_dir))
mlog.log(' -- link_libraries: ', mlog.bold(str(self.link_libraries)))
mlog.log(' -- link_with: ', mlog.bold(str(self.link_with)))
+ mlog.log(' -- object_libs: ', mlog.bold(str(self.object_libs)))
mlog.log(' -- link_flags: ', mlog.bold(str(self.link_flags)))
mlog.log(' -- languages: ', mlog.bold(str(self.languages)))
mlog.log(' -- includes: ', mlog.bold(str(self.includes)))
@@ -297,11 +311,19 @@ class CMakeInterpreter:
self.targets += [ConverterTarget(k)]
output_target_map = {x.full_name: x for x in self.targets}
+ object_libs = []
+ # First pass: Basic target cleanup
for i in self.targets:
i.postprocess(output_target_map, self.src_dir, self.install_prefix)
+ if i.type == 'OBJECT_LIBRARY':
+ object_libs += [i]
self.languages += [x for x in i.languages if x not in self.languages]
+ # Second pass: Detect object library dependencies
+ for i in self.targets:
+ i.process_object_libs(object_libs)
+
mlog.log('CMake project', mlog.bold(self.project_name), 'has', mlog.bold(str(len(self.targets))), 'build targets.')
def pretend_to_be_meson(self) -> CodeBlockNode:
@@ -342,6 +364,14 @@ class CMakeInterpreter:
func_n = FunctionNode(self.subdir, 0, 0, name, args_n)
return func_n
+ def method(obj: BaseNode, name: str, args=[], kwargs={}) -> MethodNode:
+ args_n = ArgumentNode(token())
+ if not isinstance(args, list):
+ args = [args]
+ args_n.arguments = [nodeify(x) for x in args]
+ args_n.kwargs = {k: nodeify(v) for k, v in kwargs.items()}
+ return MethodNode(self.subdir, 0, 0, obj, name, args_n)
+
def assign(var_name: str, value: BaseNode) -> AssignmentNode:
return AssignmentNode(self.subdir, 0, 0, var_name, value)
@@ -351,13 +381,19 @@ class CMakeInterpreter:
processed = {}
def process_target(tgt: ConverterTarget):
- # First handle inter dependencies
+ # First handle inter target dependencies
link_with = []
+ objec_libs = []
for i in tgt.link_with:
assert(isinstance(i, ConverterTarget))
if i.name not in processed:
process_target(i)
link_with += [id(processed[i.name]['tgt'])]
+ for i in tgt.object_libs:
+ assert(isinstance(i, ConverterTarget))
+ if i.name not in processed:
+ process_target(i)
+ objec_libs += [processed[i.name]['tgt']]
# Determine the meson function to use for the build target
tgt_func = tgt.meson_func()
@@ -379,6 +415,7 @@ class CMakeInterpreter:
'install': tgt.install,
'install_dir': tgt.install_dir,
'override_options': tgt.override_options,
+ 'objects': [method(id(x), 'extract_all_objects') for x in objec_libs],
}
# Handle compiler args
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 182326e..6d268c6 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2560,15 +2560,18 @@ external dependencies (including libraries) must go to "dependencies".''')
with mlog.nested():
mlog.log('Processing generated meson AST')
mlog.log()
- mlog.log('=== BEGIN meson.build ===')
+
+ # Debug print the generated meson file
+ mlog.debug('=== BEGIN meson.build ===')
from .ast import AstIndentationGenerator, AstPrinter
printer = AstPrinter()
ast.accept(AstIndentationGenerator())
ast.accept(printer)
printer.post_process()
- mlog.log(printer.result)
- mlog.log('=== END meson.build ===')
- mlog.log()
+ mlog.debug(printer.result)
+ mlog.debug('=== END meson.build ===')
+ mlog.debug()
+
result = self.do_subproject_meson(dirname, subdir, default_options, required, kwargs, ast, cm_int.bs_files)
mlog.log()
diff --git a/test cases/cmake/4 object library/main.cpp b/test cases/cmake/4 object library/main.cpp
new file mode 100644
index 0000000..f383608
--- /dev/null
+++ b/test cases/cmake/4 object library/main.cpp
@@ -0,0 +1,9 @@
+#include <iostream>
+#include "libA.hpp"
+#include "libB.hpp"
+
+using namespace std;
+
+int main() {
+ cout << getLibStr() << " -- " << getZlibVers() << endl;
+}
diff --git a/test cases/cmake/4 object library/meson.build b/test cases/cmake/4 object library/meson.build
new file mode 100644
index 0000000..05cd7f7
--- /dev/null
+++ b/test cases/cmake/4 object library/meson.build
@@ -0,0 +1,14 @@
+project('cmake_object_lib_test', ['cpp'])
+
+sub_pro = subproject('cmObjLib')
+sub_sha = sub_pro.get_variable('lib_sha_dep')
+sub_sta = sub_pro.get_variable('lib_sta_dep')
+
+# Required for the static library
+zlib_dep = dependency('zlib')
+
+exe_sha = executable('shared', ['main.cpp'], dependencies: [sub_sha])
+exe_sta = executable('static', ['main.cpp'], dependencies: [sub_sta, zlib_dep])
+
+test('test1', exe_sha)
+test('test1', exe_sta)
diff --git a/test cases/cmake/4 object library/subprojects/cmObjLib/CMakeLists.txt b/test cases/cmake/4 object library/subprojects/cmObjLib/CMakeLists.txt
new file mode 100644
index 0000000..ee9be47
--- /dev/null
+++ b/test cases/cmake/4 object library/subprojects/cmObjLib/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.7)
+
+find_package(ZLIB REQUIRED)
+
+add_library(lib_obj OBJECT libA.cpp libB.cpp)
+add_library(lib_sha SHARED $<TARGET_OBJECTS:lib_obj>)
+add_library(lib_sta STATIC $<TARGET_OBJECTS:lib_obj>)
+
+target_link_libraries(lib_sha ZLIB::ZLIB)
+target_link_libraries(lib_sta ZLIB::ZLIB)
diff --git a/test cases/cmake/4 object library/subprojects/cmObjLib/libA.cpp b/test cases/cmake/4 object library/subprojects/cmObjLib/libA.cpp
new file mode 100644
index 0000000..3736b2c
--- /dev/null
+++ b/test cases/cmake/4 object library/subprojects/cmObjLib/libA.cpp
@@ -0,0 +1,5 @@
+#include "libA.hpp"
+
+std::string getLibStr() {
+ return "Hello World";
+}
diff --git a/test cases/cmake/4 object library/subprojects/cmObjLib/libA.hpp b/test cases/cmake/4 object library/subprojects/cmObjLib/libA.hpp
new file mode 100644
index 0000000..58c9413
--- /dev/null
+++ b/test cases/cmake/4 object library/subprojects/cmObjLib/libA.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <string>
+
+std::string getLibStr();
diff --git a/test cases/cmake/4 object library/subprojects/cmObjLib/libB.cpp b/test cases/cmake/4 object library/subprojects/cmObjLib/libB.cpp
new file mode 100644
index 0000000..b359c29
--- /dev/null
+++ b/test cases/cmake/4 object library/subprojects/cmObjLib/libB.cpp
@@ -0,0 +1,6 @@
+#include "libB.hpp"
+#include <zlib.h>
+
+std::string getZlibVers() {
+ return zlibVersion();
+}
diff --git a/test cases/cmake/4 object library/subprojects/cmObjLib/libB.hpp b/test cases/cmake/4 object library/subprojects/cmObjLib/libB.hpp
new file mode 100644
index 0000000..71db6b7
--- /dev/null
+++ b/test cases/cmake/4 object library/subprojects/cmObjLib/libB.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <string>
+
+std::string getZlibVers();