building with gtest gtest_force_shared_crt doesn't work - c++11

I have a project set to link with gtest like so:
FetchContent_Declare(googletest
GIT_REPOSITORY https://github.com/google/googletest
GIT_TAG master
)
FetchContent_MakeAvailable(googletest)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
target_link_libraries(testlib PRIVATE projlib gtest_main)
as you can see I link to gtest and also make sure to set:
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
yet when I build my projblib with cmake I get that the run time library version still mismatch:
gtestd.lib(gtest-all.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't matc
h value 'MDd_DynamicDebug'
Not sure why this happens and how to fix this, suggestions?

Related

Unexpected path to libprotocd.lib after add gRPC::grpc++ library dependence in CMake

I have a gRPC 1.23.0 compiled by conan(and all dependencies also resolved by conan).
And I have a CMake project, that use grpc library:
set (LIB_DEPS
protobuf::libprotobuf
gRPC::grpc++
)
target_link_libraries(${PROJECT_NAME} PUBLIC ${LIB_DEPS})
When I generate a VS project from this CMakeLists.txt in Linker - Input - Addition Dependencies property, I have there next value:
C:\.conan\data\protobuf\3.9.1\kpa_conan\stable\package\b786e9ece960c3a76378ca4d5b0d0e922f4cedc1\lib\libprotobufd.lib <-- (1)
C:\.conan\data\grpc\1.23.0\kpa_conan\stable\package\d85cccdf40588ac852bd1445d45838487543194f\lib\grpc++.lib
libprotocd.lib <-- (2)
libprotobufd.lib <-- (3)
C:\.conan\data\grpc\1.23.0\kpa_conan\stable\package\d85cccdf40588ac852bd1445d45838487543194f\lib\grpc.lib
C:\.conan\data\grpc\1.23.0\kpa_conan\stable\package\d85cccdf40588ac852bd1445d45838487543194f\lib\gpr.lib
C:\.conan\data\c-ares\1.15.0\kpa_conan\stable\package\b786e9ece960c3a76378ca4d5b0d0e922f4cedc1\lib\cares.lib
C:\.conan\data\grpc\1.23.0\kpa_conan\stable\package\d85cccdf40588ac852bd1445d45838487543194f\lib\address_sorting.lib
wsock32.lib
kernel32.lib
(1) - expected valid path, that I add in CMakeLists.txt
(2),(3) - unexpected and invalid path, that added by gRPC::grpc++ in CMakeLists.txt.
If I change gRPC::grpc++ to gRPC::grpc, lines (2) and (3) will disappear, but path to grpc++.lib will disappear too, but I need it.
How to avoid this strange invalid path to libprotocd.lib and libprotobufd.lib?
To properly link against grpc targets you can use:
target_link_libraries(${PROJECT_NAME} PUBLIC CONAN_PKG::grpc)
This should contain everything required.
More details on this approach here: https://docs.conan.io/en/latest/integrations/build_system/cmake/cmake_generator.html#targets-approach
I have found workaround solution:
find_library(GRPC_GRPC++_LIBRARY NAMES grpc++)
set (LIB_DEPS
protobuf::libprotobuf
gRPC::grpc
${GRPC_GRPC++_LIBRARY NAMES}
)
target_link_libraries(${PROJECT_NAME} PUBLIC ${LIB_DEPS})
And opened the issue about it in gRPC repository: https://github.com/grpc/grpc/issues/20578

Xcode watch 'invalid expression'

I'm stepping through some Swift code in Xcode and I'd like to watch values. Following the advice in many of the answers here (e.g. this one) I can add the expression to the local variables window.
The breakpoint I am on is the last line of this fragment from the Starscream library (by daltoniam) which I include as a pod.
for i in 0..<dataLength {
buffer[offset] = data[i] ^ maskKey[i % MemoryLayout<UInt32>.size]
offset += 1
}
var total = 0
I've added two expressions to watch:
buffer[0] and
MemoryLayout<UInt32>.size
For both the value I see is "invalid expression":
These expressions are clearly are not invalid, if they were the code would have thrown an exception when they were encountered executing the previous few lines. What am I missing? How should I watch and not get 'invalid expression'
N.B. If I call p buffer[0] from the lldb prompt I get the cryptic error:
(lldb) p buffer[0]
error: warning: :12:9: warning: initialization of variable
'$__lldb_error_result' was never used; consider replacing with assignment to '_'
or removing it
var $__lldb_error_result = __lldb_tmp_error
~~~~^~~~~~~~~~~~~~~~~~~~
_
error: :19:5: error: value of type 'WebSocket' has no member
'$__lldb_wrapped_expr_72'
$__lldb_injected_self.$__lldb_wrapped_expr_72(
^~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
I have tried changing the podfile (as per Jim's answer) so that it explicitly gets the debug code:
pod 'Starscream', '~> 3.0.6', :configuration => 'Debug'
and I have even gone as far as removing the pods, cloning Starscream, and including the source code as a sub-project. I still get the same error.
An expression that accesses buffer[0] where buffer is a UnsafeMutablePointer works correctly in the expression parser when I'm stopped in some simple function. And from your experience with the expr command directly, it looks like your problem is not with this particular expression. Rather it looks like there's something about the context you are stopped in that's tripping up the expression parser altogether.
Make sure that you aren't using binary cocoapods's and that you've rebuilt all your code and all the pods you are using have been rebuilt from scratch with the same swift compiler. At present, lldb and swiftc are version locked - lldb can only debug programs built with the swiftc that it ships with.
If that doesn't fix the issue, then we'll need to figure out what about the particular function you are stopped in that's causing the problem. This seems like the sort of thing better dealt with by filing a bug with the swift project (http://bugs.swift.org).

Why do I get undeclared inclusion error when using the lib as external library?

I am trying to include an external library (glm) in my bazel build, but I get undeclared inclusion the thing is I don't understand how to fix it and why, Because if I use the same BUILD script when I extract manually the library it builds fine.
I managed to make a very small repro of this problem, both the working case and the not working.
The not working example
My folder structure
glmExtBuild
WORKSPACE
externals
glm.BUILD
This is my WORKSPACE file
new_http_archive(
name = "glmExt",
url = "https://github.com/g-truc/glm/archive/0.9.9.0.tar.gz",
sha256 = "514dea9ac0099dc389cf293cf1ab3d97aff080abad55bf79d4ab7ff6895ee69c",
strip_prefix = "glm-0.9.9.0",
build_file = "externals/glm.BUILD",
)
This is my glm.BUILD file
package(default_visibility = ["//visibility:public"])
cc_library(
name= "glm",
defines= ["GLM_ENABLE_EXPERIMENTAL", "GLM_FORCE_RADIANS",
"GLM_FORCE_DEPTH_ZERO_TO_ONE"],
srcs=glob(["glm/**/*.cpp"]) + ["glm/detail/_fixes.hpp"],
hdrs=glob(["glm/**/*.hpp"])+glob(["glm/**/*.h"]),
includes = ["glm"],
textual_hdrs = glob(["glm/**/*.inl"]),
visibility = ["//visibility:public"],
)
And this is the errors that I get when I run
bazel build #glmExt//:glm --verbose_failures --sandbox_debug
ERROR: C:/users/...../external/glmExt/BUILD.bazel:121:1: undeclared inclusion(s) in rule '#glmExt//:glm':
this rule is missing dependency declarations for the following files included by 'external/glmExt/glm/detail/glm.cpp':
'external/glmext/glm/detail/_fixes.hpp'
'external/glmext/glm/detail/setup.hpp'
'external/glmext/glm/simd/platform.h'
'external/glmext/glm/fwd.hpp'
'external/glmext/glm/detail/setup.hpp'
'external/glmext/glm/detail/type_int.hpp'
'external/glmext/glm/detail/setup.hpp'
'external/glmext/glm/detail/type_float.hpp'
...
The working example:
My folder structure
glmBuild2
WORKSPACE
BUILD
glmSrc
https://github.com/g-truc/glm/archive/0.9.9.0.tar.gz extracted here
My WORKSPACE file is empty
And this is my BUILD file
package(default_visibility = ["//visibility:public"])
cc_library(
name= "glm",
defines= ["GLM_ENABLE_EXPERIMENTAL", "GLM_FORCE_RADIANS", "GLM_FORCE_DEPTH_ZERO_TO_ONE"],
srcs=glob(["glmSrc/glm/**/*.cpp"]) + ["glmSrc/glm/detail/_fixes.hpp"],
hdrs=glob(["glmSrc/glm/**/*.hpp"])+glob(["glmSrc/glm/**/*.h"]),
includes = ["glmSrc"],
textual_hdrs = glob(["glmSrc/glm/**/*.inl"]),
visibility = ["//visibility:public"],
)
Then when running the build command it finished successfully.
PS D:\......\glmBuild2> bazel build :glm --verbose_failures --sandbox_debug
INFO: Analysed target //:glm (1 packages loaded).
INFO: Found 1 target...
INFO: From Compiling glmSrc/glm/detail/glm.cpp:
glmSrc/glm/detail/glm.cpp(4): warning C4005: 'GLM_ENABLE_EXPERIMENTAL': macro redefinition
glmSrc/glm/detail/glm.cpp(4): note: command-line arguments: see previous definition of 'GLM_ENABLE_EXPERIMENTAL'
Target //:glm up-to-date:
C:/users/.../execroot/__main__/bazel-out/x64_windows-fastbuild/bin/libglm.a
INFO: Elapsed time: 1.830s, Critical Path: 1.30s
INFO: 3 processes, local.
INFO: Build completed successfully, 4 total actions
Does anybody have an idea?
Thanks
Update:
bazel version
Build label: 0.14.0
Build target: bazel-out/x64_windows-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Fri Jun 1 13:06:29 2018 (1527858389)
Build timestamp: 1527858389
Build timestamp as int: 1527858389
Bazel issue:
https://github.com/bazelbuild/bazel/issues/5485
I tried the first example on linux, with bazel 0.15.0, and all worked once I added "." into includes attribute of glm. Do you have a possibility to test it on linux? Is it windows-only issue then? Which bazel version do you use?
Thanks for clarifications.

Failing to build Boost components locally with Bazel build

I am trying to build Boost library locally and want to use it as a local_repository in my own project. I am referring to this (https://github.com/nelhage/rules_boost) for help.
I have a directory tree like this:
boost/ // root of the boost project
|
bazel/
| |
| boost.bzl // contains "boost_library" function from https://github.com/nelhage/rules_boost/blob/master/boost/boost.bzl
| |
| BUILD // empty
boost/ // the original boost headers folder from original boost dist
|
lib/ // the original boost sources folder from original boost dist
|
BUILD
|
WORKSPACE
The BUILD file looks like this one:
https://github.com/nelhage/rules_boost/blob/master/BUILD.boost
with properly loading boost.bzl
The WORKSPACE is just:
workspace( name = "boost" )
The issue:
Now I am trying to build individual components (bazel build //:<component>).
Some of the components (Boost.Container, Boost.Test) are failing to build for a similar reason (not finding header files).
bazel build //:container 1 ↵
INFO: Found 1 target...
ERROR: /home/spyder/codebase/boost/BUILD:103:1: C++ compilation of rule '//:container' failed: Process exited with status 1 [sandboxed].
libs/container/src/global_resource.cpp:12:51: fatal error: boost/container/pmr/memory_resource.hpp: No such file or directory
compilation terminated.
Use --strategy=CppCompile=standalone to disable sandboxing for the failing actions.
Target //:container failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.519s, Critical Path: 0.18s
bazel build //:test 1 ↵
INFO: Found 1 target...
ERROR: /home/spyder/codebase/boost/BUILD:581:1: C++ compilation of rule '//:test' failed: Process exited with status 1 [sandboxed].
libs/test/src/junit_log_formatter.cpp:11:51: fatal error: boost/test/impl/junit_log_formatter.ipp: No such file or directory
compilation terminated.
Use --strategy=CppCompile=standalone to disable sandboxing for the failing actions.
Target //:test failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 1.027s, Critical Path: 0.82s
Can anyone guide me on fixing it ?
EDIT:
I also tried to query the expanded cc_library rule by bazel query --output=build //:container and got this
cc_library(
name = "container",
visibility = ["//visibility:public"],
generator_name = "container",
generator_function = "boost_library",
generator_location = "/home/spyder/codebase/boost/BUILD:103",
licenses = ["notice"],
deps = ["//:config", "//:core", "//:intrusive", "//:move"],
defines = [],
includes = ["boost/container/"],
copts = ["-Wno-unused-value"],
srcs = ["//:libs/container/src/alloc_lib.c", "//:libs/container/src/dlmalloc.cpp", "//:libs/container/src/dlmalloc_2_8_6.c", "//:libs/container/src/dlmalloc_ext_2_8_6.c", "//:libs/container/src/global_resource.cpp", "//:libs/container/src/monotonic_buffer_resource.cpp", "//:libs/container/src/pool_resource.cpp", "//:libs/container/src/synchronized_pool_resource.cpp", "//:libs/container/src/unsynchronized_pool_resource.cpp"],
hdrs = [ ....... , "//:boost/container/pmr/map.hpp", "//:boost/container/pmr/memory_resource.hpp", "//:boost/container/pmr/monotonic_buffer_resource.hpp", "//:boost/container/pmr/polymorphic_allocator.hpp", ........ ],
)
Very shockingly, the source file which is complaining (libs/container/src/global_resource.cpp) and the header that it is complaining about (boost/container/pmr/memory_resource.hpp) are both correctly included in the srcs and hdrs list.
I played with your rules a bit and the biggest problem I see is incomplete dependencies. For example I tried :algorithm component, and that needs to depend on :tuple. I guess you just needs to make sure all dependencies are set correctly.
I played more with container, and the problem I encountered was incorrect include dirs. If you run your build with -s flag, bazel will output all the command lines so you can inspect them and check that -isystem flags contain the directory that contains boost/container/... . What can also help you is the bazel flag --sandbox_debug, which will prevent the sandbox directory from being deleted so you can see which files are where and also you can reproduce the compiler invocation without running through bazel.
Last, bazel does not understand .ipp header extension yet (tbh I've never heard of it, but I also know next to nothing about boost). I have a change in flight that will introduce this.

DSO library symbol seems to have DEFAULT visibility although should be HIDDEN

I have a problem with setting up a visibility of my shared library. I would like to ask for help in resolving my issue as described below:
I have a bunch of source files which I would like to build as shared library:
+Base
|_Parameter
| |_Parameter.h
| |_Parameter_Exception.h
| |_Parameter_Exception.cpp
|_Data
| |_DataInput.h
| |_DataInput_Exception.h
| |_DataInput_Exception.cpp
...
Well there are some more files in there but I think it does not influence my problem description.
I am using CMake in order to build this SHARED library. Here is part of my CMakeLists.txt which deals with building the library.
project( Base )
cmake_minimum_required(VERSION 3.5
set( Base_HEADERS
Parameter/Parameter.h
Parameter/Parameter_Exception.h
Data/DataInput.h
Data/DataInput_Exception.h
)
set( Base_SOURCES
Parameter/Parameter_Exception.cpp
Data/DataInput_Exception.cpp
)
set( LIBRARY_OUTPUT_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} )
add_library( Base SHARED ${Base_SOURCES} ${Base_HEADERS} )
generate_export_header( ${PROJECT_NAME} EXPORT_FILE_NAME ${PROJECT_NAME}_Export.h )
This setup builds libBase.so shared library without any problem. It is important to mention that I have set some visibility related flags to be used during linking:
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -fvisibility=hidden -fvisibility-inlines-hidden" )
As configured in Base library CMakeLists.txt partly listed above:
Base_Export.h header containig GCC visibility attributes macros is
generated by CMake. It is then included in my sources listed in the
tree up there.
By default all the symbols shall be hidden as set in
linker flags (-fvisibility=hidden)
For example a piece of Parameter_Exception.h:
#include "Base_Export.h"
class SomeException : public std::exception
{
public:
SomeException( void ) {}
...
};
Please notice I have not set any visibility attribute here (by a macro defined in Base_Export). So I would assume, the symbol of SomeException class shall be hidden to all the DSO "users" (due to -fvisibility=hidden)
But it doesn't seem so. Unfortunately:
Once I use the library, it the exception is usable although the symbol should be hidden. I would expect link failure cause by this code snippet "outside the library":
#include "Parameter/Parameter_Exception.h"
...
try
{
...
}
/* THIS SHOULD FAIL IN LINKING DUE TO UNDEFINED SYMBOL, RIGHT? */
catch( const SomeException & e )
{
...
}
I have also tried to look for the symbol in the libBase.so using the command:
readelf -Ws libBase.so
it lists enormously long text:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 000000000008b7e0 0 SECTION LOCAL DEFAULT 9
....
but what I have noticed here is that in "Vis" column up there there is always DEFAULT which implies a default visibility ( __attribute__((visibility("default"))) ) to me BUT I would expect to see HIDDEN in there ( __attribute__((visibility("hidden"))) )
So what am I doing wrong? Or my understanding is not correct? I know all the linked flags are propagated correctly but seem to have no effect.
My toolchain configuration as listed by CMake configuration script (GCC version that supports visibility attributes):
...
-- The CXX compiler identification is GNU 5.3.1
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
...
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Configuring done
-- Generating done
Many thanks in advance to anybody willing to help me and possibly others having the same trouble as I do.
Thanks again, Martin
CMake has direct support for symbol visibility handling, so you shouldn't need to touch CMAKE_SHARED_LINKER_FLAGS or CMAKE_CXX_FLAGS at all. You can set the visibility on a per-target basis like this:
set_target_properties(Base PROPERTIES
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN YES
)
CMake will then ensure the relevant flags are added for you. Rather than having to set these properties for each target, it is usually more convenient to set the associated variables to set the defaults for all subsequently created targets (and this is what I generally recommend and use in projects I work on):
cmake_minimum_required(VERSION 3.5)
project(Base)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
add_library(Base SHARED ...)
When used in conjunction with the GenerateExportHeader module (which you already appear to be using), you get support not just for gcc/clang, but also Visual Studio, making it a nice cross-platform way of controlling symbol visibility. You don't need to know the relevant compiler flags or attributes, CMake will handle them for you and give you equivalent behavior across all the compilers.
-fvisibility=hidden and -fvisibility-inlines-hidden are compiler options,
not linker options. Set them in CMAKE_CXX_FLAGS

Resources