如何正确使用生成的 protobuf 源?
How to use generated protobuf sources correctly?
当我尝试使用 protobuf 生成的源时,'-std=c++11' 被添加到我尝试在其中使用它们的目标的编译标志中,导致编译失败(因为我正在使用 post C++11 特性)。
以下是一个非常小的例子。
3 个文件,全部在一个目录中:
meson.build
project('test', 'cpp',
version : '0.1',
default_options : ['warning_level=3', 'cpp_std=c++17', 'werror=true']
)
protoc = find_program('protoc')
proto_dep = dependency('protobuf')
gen = generator(protoc,
output : ['@BASENAME@.pb.cc', '@BASENAME@.pb.h'],
arguments : ['--proto_path=@CURRENT_SOURCE_DIR@', '--cpp_out=@BUILD_DIR@', '@INPUT@'])
generated = gen.process(['defs.proto'])
test_exe = executable(
'test_exe',
'main.cpp',
generated,
dependencies : proto_dep
)
main.cpp
#include "defs.pb.h"
#include <chrono>
int main()
{
using namespace std::chrono_literals;
}
defs.proto
syntax = "proto2";
package messages;
message Person {
required string node= 1;
required string payload= 2;
}
在 运行 meson build && ninja
之后失败并出现以下错误:
[1/3] Compiling C++ object 'test_exe@exe/main.cpp.o'.
FAILED: test_exe@exe/main.cpp.o
c++ -Itest_exe@exe -I. -I.. -I/usr/local/include -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -Werror -std=c++17 -g -pthread -g -std=c++11 -DNDEBUG -MD -MQ 'test_exe@exe/main.cpp.o' -MF 'test_exe@exe/main.cpp.o.d' -o 'test_exe@exe/main.cpp.o' -c ../main.cpp
../main.cpp: In function ‘int main()’:
../main.cpp:6:24: error: ‘chrono_literals’ is not a namespace-name
using namespace std::chrono_literals;
^~~~~~~~~~~~~~~
../main.cpp:6:39: error: expected namespace-name before ‘;’ token
using namespace std::chrono_literals;
^
[2/3] Compiling C++ object 'test...e/meson-generated_defs.pb.cc.o'.
ninja: build stopped: subcommand failed.
问题是:如何修复 meson.build 文件,以便正确生成源文件,并且 project( default_options
仅指定传递的 std=
标志?
所以我找到了一个解决问题的方法,你可以通过在 cpp_args 中为目标传递 '-std=c++17' 来编译它,具体取决于 protobuf。
proto_interface = declare_dependency(
sources : generated,
dependencies : proto_dep
)
test_exe = executable(
'test_exe',
'main.cpp',
dependencies : proto_interface,
cpp_args : ['-std=c++17']
)
这似乎不是很干净,因为有 3 个 -std
标志通过这种方式传递给 test_exe
来源,就像下面来自 compile_commands.json
的片段:
-std=c++17 -g -pthread -g -std=c++11 -DNDEBUG -std=c++17
您可以使用
禁用所有依赖项 cxxflags
proto_dep = dependency('protobuf').partial_dependency(compile_args : false,
link_args : true, links : true, includes : true, source : true)
如果缺少任何重要的标志,您可以手动将它们添加回来。
当我尝试使用 protobuf 生成的源时,'-std=c++11' 被添加到我尝试在其中使用它们的目标的编译标志中,导致编译失败(因为我正在使用 post C++11 特性)。
以下是一个非常小的例子。
3 个文件,全部在一个目录中:
meson.build
project('test', 'cpp',
version : '0.1',
default_options : ['warning_level=3', 'cpp_std=c++17', 'werror=true']
)
protoc = find_program('protoc')
proto_dep = dependency('protobuf')
gen = generator(protoc,
output : ['@BASENAME@.pb.cc', '@BASENAME@.pb.h'],
arguments : ['--proto_path=@CURRENT_SOURCE_DIR@', '--cpp_out=@BUILD_DIR@', '@INPUT@'])
generated = gen.process(['defs.proto'])
test_exe = executable(
'test_exe',
'main.cpp',
generated,
dependencies : proto_dep
)
main.cpp
#include "defs.pb.h"
#include <chrono>
int main()
{
using namespace std::chrono_literals;
}
defs.proto
syntax = "proto2";
package messages;
message Person {
required string node= 1;
required string payload= 2;
}
在 运行 meson build && ninja
之后失败并出现以下错误:
[1/3] Compiling C++ object 'test_exe@exe/main.cpp.o'.
FAILED: test_exe@exe/main.cpp.o
c++ -Itest_exe@exe -I. -I.. -I/usr/local/include -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -Werror -std=c++17 -g -pthread -g -std=c++11 -DNDEBUG -MD -MQ 'test_exe@exe/main.cpp.o' -MF 'test_exe@exe/main.cpp.o.d' -o 'test_exe@exe/main.cpp.o' -c ../main.cpp
../main.cpp: In function ‘int main()’:
../main.cpp:6:24: error: ‘chrono_literals’ is not a namespace-name
using namespace std::chrono_literals;
^~~~~~~~~~~~~~~
../main.cpp:6:39: error: expected namespace-name before ‘;’ token
using namespace std::chrono_literals;
^
[2/3] Compiling C++ object 'test...e/meson-generated_defs.pb.cc.o'.
ninja: build stopped: subcommand failed.
问题是:如何修复 meson.build 文件,以便正确生成源文件,并且 project( default_options
仅指定传递的 std=
标志?
所以我找到了一个解决问题的方法,你可以通过在 cpp_args 中为目标传递 '-std=c++17' 来编译它,具体取决于 protobuf。
proto_interface = declare_dependency(
sources : generated,
dependencies : proto_dep
)
test_exe = executable(
'test_exe',
'main.cpp',
dependencies : proto_interface,
cpp_args : ['-std=c++17']
)
这似乎不是很干净,因为有 3 个 -std
标志通过这种方式传递给 test_exe
来源,就像下面来自 compile_commands.json
的片段:
-std=c++17 -g -pthread -g -std=c++11 -DNDEBUG -std=c++17
您可以使用
禁用所有依赖项 cxxflagsproto_dep = dependency('protobuf').partial_dependency(compile_args : false,
link_args : true, links : true, includes : true, source : true)
如果缺少任何重要的标志,您可以手动将它们添加回来。