Cannot get lldb location to resolve - cmake

I am attempting to compile and debug from the command line, using cmake and lldb. I'm not sure why this isn't working:
cmake_minimum_required (VERSION 2.6)
project (etest)
include_directories(src)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -g")
add_executable(etest src/m.cpp)
set_property(TARGET etest PROPERTY CXX_STANDARD 14)
set_property(TARGET etest PROPERTY CXX_STANDARD_REQUIRED ON)
Then:
~/Desktop/em2 cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/jbake/Desktop/em2
~/Desktop/em2 make
[ 50%] Building CXX object CMakeFiles/etest.dir/src/m.cpp.o
[100%] Linking CXX executable etest
[100%] Built target etest
~/Desktop/em2 lldb etest
(lldb) target create "etest"
Current executable set to 'etest' (x86_64).
(lldb) b src/m.cpp:7
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) breakpoint list
Current breakpoints:
1: file = 'src/m.cpp', line = 7, locations = 0 (pending)
I thought the -g option was necessary to get debug locations added to the executable for use with lldb, but I've been trying various tweaks for hours and cannot get anything to resolve. What am I missing?

There's a bug in lldb that means you either have to set a breakpoint with JUST the file name, or you have to use the full path as recorded in the debug information. Partial paths should work, but don't at present.
Using full paths is tricky if you have a build system that moves files around or refers to them through symbolic links. Then you have to get the path as spelled to the compiler. You can find this by doing:
(lldb) break set -f JustTheName.cpp -l 10
Then grab the address that the breakpoint was set at, and do:
(lldb) image lookup -v -a <BREAK_ADDRESS>
The file in the CompileUnit part of this output will be the path as spelled in the debug information.

Related

build yaml-cpp lib with -m32 (32-bit) - on linux /w gcc or llvm

subject pretty much says it all:
I downloaded yaml-cpp version 0.6.3.
I need to compile on linux x86_64, target linux x86_32 (build on 64 bit, use result on 32-bit)
I have been trying to add a new "YAML_BUILD_32BIT" option - similar to the existing YAML_BUILD_SHARED_LIBS option.
When I detect YAML_BUILD_32BIT is set: I try to add "-m32" to a bunch of cmake variables.
My problem is that this list of variables seems endless or not well defined.
"yaml_cxx_flags" are passed to the compile and link steps for the yaml-cpp library code...but not to build the google 'mock' code. Similarly, I found other variables that I can also set, so that google-mock is compiled with -m32 as well...but then the yaml-cpp mock tests do not see the flag...and so on and so on.
I think I am missing something very fundamental. I expect that there will be a single variable I need to update...maybe 2 or 3. I don't expect to keep finding more and more.
--
Adding more specifics:
To CMakeLists.txt:
added line (immediately after the similar line which creates the YAML_BUILD_SHARED_LIBS flag)
option(YAML_BUILD_32BIT "Build with '-m32'" OFF)
then a bit later (immediately after the YAML_BUILD_SHARED_LIBS if/else):
if(YAML_BUILD_32BIT)
# seem to need this one for the shared lib link of yaml-cpp lib
# CXX_FLAGS passed to both compile and link
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
# seem to need this one, to get flag passed to gmock build
set(FLAG_TESTED "${FLAG_TESTED} -m32")
# this one passed to compile and link of testcase
set(yaml_cxx_flags "${yaml_cxx_flags} -m32")
endif()
and made "FLAG_TESTED" addive, on immediately following line:
set(FLAG_TESTED "-Wextra -Wshadow -Weffc++ -pedantic -pedantic-errors ${FLAG_TESTED}")
Given the above, then configuring with:
# using cmake/3.19.3
cmake -G "Unix Makefiles" -DYAML_BUILD_SHARED_LIBS=ON -DYAML_BUILD_32BIT=ON"
... and then building with 'make VERBOSE=1', I see that 'gmock-all.cc.o' did not receive the -m32 flag. (gmock-all.cc.o is only the first such file in my log..there are others.)
If I remove other of the lines in my CMakeLists.txt which attempted to add flags - then other compile commands or other link commands don't see -m32 and will fail.
As I said: I think there is something fundamental that I have misunderstood. I suspect that it is much easier to configure a 32-bit build than I am making it.
With some help from a coworker, I ended up doing the following:
top-level CMakeLists.txt file (near line 28, immediately following definition of YAML_BUILD_SHARED_LIBS variable):
option(YAML_BUILD_32BIT "Build with '-m32'" OFF)
if(YAML_BUILD_32BIT)
add_compile_options(-m32)
add_link_options(-m32)
endif()
in .../test/CMakeLists.txt (near line 10):
if(YAML_BUILD_32BIT)
set(GTEST_EXTRA_FLAGS "-DCMAKE_CXX_FLAGS=-m32")
endif()
then add new flag to "ExternalProject_Add(..." call (near line .../test/CMakeLists.txt:22):
ExternalProject_Add(
googletest_project
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/gtest-1.8.0"
INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/prefix"
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DBUILD_GMOCK=ON
-Dgtest_force_shared_crt=ON
${GTEST_EXTRA_FLAGS} # <- this line added
)
The above has the effect of passing the extra "-m32" flag the embedded gmocktest project.
Given the above changes, the cmake command line above generates something that will build successfully (at least on RHEL-7, with gcc/5.2.0)
Hope this can help somebody else.
Henry

How to find compiler path automatically in cmake?

I want to set compiler path (for example:icc) automatically in cmake, so my program can compile at any computer as long as it have installed icc, and we do not need to care about where the icc is installed.
At First, I using the follow command to set compiler. Everything is OK.
set(Intel_C_COMPILER "/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc")
set(Intel_CXX_COMPILER "/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc")
set(CMAKE_C_COMPILER ${Intel_C_COMPILER} )
set(CMAKE_CXX_COMPILER ${Intel_CXX_COMPILER})
project(MyProject)
....
Then, I want to set compiler path automatically, I know that the follow command can find compiler path
which icc
So I write the follow command try to set compiler automatically by cmake.
execute_process(COMMAND which icc OUTPUT_VARIABLE Intel_C_COMPILER)
execute_process(COMMAND which icpc OUTPUT_VARIABLE Intel_CXX_COMPILER)
message(Intel_CXX_COMPILER: ${Intel_C_COMPILER})
message(Intel_CXX_COMPILER: ${Intel_CXX_COMPILER})
set(CMAKE_C_COMPILER ${Intel_C_COMPILER} )
set(CMAKE_CXX_COMPILER ${Intel_CXX_COMPILER})
project(MyProject)
....
At these case, something strange happens, cmake shows that:
Intel_CXX_COMPILER:/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc
-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
CMake Error at CMakeLists.txt:27 (project): The CMAKE_C_COMPILER:
/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc
is not a full path to an existing compiler tool.
Tell CMake where to find the compiler by setting either the
environment variable "CC" or the CMake cache entry CMAKE_C_COMPILER
to the full path to the compiler, or to the compiler name if it is
in the PATH.
CMake Error at CMakeLists.txt:27 (project): The CMAKE_CXX_COMPILER:
/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc
is not a full path to an existing compiler tool.
Tell CMake where to find the compiler by setting either the
environment variable "CXX" or the CMake cache entry
CMAKE_CXX_COMPILER to the full path to the compiler, or to the
compiler name if it is in the PATH.
-- Configuring incomplete, errors occurred!
CMake said that the path is not a full path to an existing compiler, but as shown in the message, it is just where the compiler located!
I know there are other techniques that we can set compiler, for example export some environment variables to help cmake find the path, but I want to know why my method dose not work?
Is there any better way can handle this problem?
Thanks in advance.
Variables Intel_C_COMPILER and Intel_CXX_COMPILER have trailing newline. Way for removing that newline are described in that question and its answers: How to strip trailing whitespace in CMake variable?
E.g., you may run execute_process with OUTPUT_STRIP_TRAILING_WHITESPACE option, so it will behave similar to the shell's backtick operator (`which icc`).
Detailed description
Most of shell utilities output single- (or even multi-) line information with trailing newline. And utility which is not an exception. With trailing newline an output looks nice when one run these utilities in the terminal.
But when run such utility in the script and grab its output programmatically, one need to care about such newline.
Generally speaking, it is not possible to set the variables CMAKE_C_COMPILER and CMAKE_CXX_COMPILER from within a project.
Since the compiler detection happens with the project() call, the compiler has to be set early on while configuring the project.
I suggest you try the following:
export CC=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc
export CXX=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc
cd /path/to/build
cmake /path/to/src
or you could also pass the variables CMAKE_C_COMPILER and CMAKE_CXX_COMPILER:
export CC=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc
export CXX=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc
cd /path/to/build
cmake \
-DCMAKE_C_COMPILER:FILEPATH=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc \
-DCMAKE_CXX_COMPILER:FILEPATH=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc \
/path/to/src
Important: When trying these commands, make sure to configure the project in an empty build directory.

Cppcheck support in CMake

I am not asking about the various available third-party modules that support Cppcheck in one way or the other.
With CMake 3.10, CMake seems to have gained some official Cppcheck support. See CMAKE_<LANG>_CPPCHECK.
Unfortunately the documentation how to use this variable is a bit sparse. Is there a good example of how Cppcheck is supposed to be used with CMake 3.10 (or later)?
An simple example would be - if you have cppcheck in your PATH and you are not specifying additional parameters - the following by setting global CMAKE_<LANG>_CPPCHECK variable:
cmake_minimum_required(VERSION 3.10)
project(CppCheckTest)
file(
WRITE "main.cpp"
[=[
int main()
{
char a[10];
a[10] = 0;
return 0;
}
]=]
)
set(CMAKE_CXX_CPPCHECK "cppcheck")
add_executable(${PROJECT_NAME} "main.cpp")
The files to scan are added automatically to the cppcheck command line. So the above example gives the following output (gcc and cppcheck on Linux system):
# make
Scanning dependencies of target CppCheckTest
[ 50%] Building CXX object CMakeFiles/CppCheckTest.dir/main.cpp.o
Checking .../CppCheckTest/main.cpp...
Warning: cppcheck reported diagnostics:
[/mnt/c/temp/StackOverflow/CppCheckTest/main.cpp:4]: (error) Array 'a[10]' accessed at index 10, which is out of bounds.
[100%] Linking CXX executable CppCheckTest
[100%] Built target CppCheckTest
You could give cppcheck a try in an existing project by simply setting the CMAKE_CXX_CPPCHECK variable via the cmake command line:
# cmake -DCMAKE_CXX_CPPCHECK:FILEPATH=cppcheck ..
A more "daily life" example would probably for you to include something like the following code snippet in your CMakeList.txt:
find_program(CMAKE_CXX_CPPCHECK NAMES cppcheck)
if (CMAKE_CXX_CPPCHECK)
list(
APPEND CMAKE_CXX_CPPCHECK
"--enable=warning"
"--inconclusive"
"--force"
"--inline-suppr"
"--suppressions-list=${CMAKE_SOURCE_DIR}/CppCheckSuppressions.txt"
)
endif()
References
CMake Commit: Add properties to run cppcheck along with the compiler
<LANG>_CPPCHECK target property
This property is supported only when <LANG> is C or CXX.
Specify a ;-list containing a command line for the cppcheck static analysis tool. The Makefile Generators and the Ninja generator will run cppcheck along with the compiler and report any problems.
This property is initialized by the value of the CMAKE_<LANG>_CPPCHECK variable if it is set when a target is created.

Check CMake Cache Variable in Toolchain File

I'm having trouble setting a configuration variable via the command line. I can't determine it from the system, so I expect the user to specify:
cmake -DCMAKE_TOOLCHAIN_FILE=../android.toolchain -DANDROID_ABI:STRING="arm64" ..
Inside my android.toolchain, I have the following:
message(STATUS "Android ABI: ${ANDROID_ABI}")
if( "${ANDROID_ABI}" STREQUAL "" )
message(FATAL_ERROR "Please specifiy ABI at cmake call -DANDROID_ABI:STRING=armeabi or -DANDROID_ABI:STRING=arm64")
endif()
No matter what, it fails at this line EVEN THOUGH it prints out the correct arm64:
-- Android ABI: arm64
CMake Error at yaml-cpp/android.toolchain:45 (message):
Please specifiy ABI at cmake call -DANDROID_ABI:STRING=armeabi or -DANDROID_ABI:STRING=arm64
Could anyone direct me to what I'm doing wrong?
I think this has to do with:
-D adds a cache variable instead of a normal variable
This is in a toolchain file... it seems to ignore cache variables
Any thoughts or suggestions?
I don't pretend to fully understand what's going on behind the scenes, but here's a workaround that works for me:
# Problem: CMake runs toolchain files multiple times, but can't read cache variables on some runs.
# Workaround: On first run (in which cache variables are always accessible), set an intermediary environment variable.
if (FOO)
# Environment variables are always preserved.
set(ENV{_FOO} "${FOO}")
else ()
set(FOO "$ENV{_FOO}")
endif ()
CMake 3.6 introduces variable CMAKE_TRY_COMPILE_PLATFORM_VARIABLES which contains a list of variables, automatically passed from the main project to the project, created with try_compile.
A toolchain may add its variables to that list, so they could be extracted in a subproject:
message(STATUS "Android ABI: ${ANDROID_ABI}")
if( "${ANDROID_ABI}" STREQUAL "" )
message(FATAL_ERROR "Please specifiy ABI at cmake call -DANDROID_ABI:STRING=armeabi or -DANDROID_ABI:STRING=arm64")
endif()
# propagate the variable into "inner" subprojects.
list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES "ANDROID_ABI")
Caveats:
This approach affects only to source flow of try_compile command. It won't work when try_compile is used for create fully-fledged CMake project with signature
try_compile(<resultVar> <bindir> <srcdir> <projectName> ...)
(Approach with setting environment variable, as described in the #sorbet answer, works perfectly in this case.)
This approach won't work for a subproject, created with ExternalProject_Add.
(Approach with setting environment variable fails in that case too.)

Compiling a CMake project against libraries in a non-standard location

I have two projects using CMake.
The first is a shared library. It compiles and installs fine. Currently, it is still necessary to build 'debug' releases of it. So presently it is installed under ~/localdebug. That folder looks like the root of a filesystem with a 'include' and 'lib' directory. The same concept as '/usr/local'.
The second is a program. It needs to compile and link against my library in ~/localdebug. The CMakeLists.txt file for it looks like this:
cmake_minimum_required(VERSION 2.6)
set(CMAKE_C_FLAGS "-std=gnu99")
#add_definitions(-pg)
find_library(SANDGROUSE_LIB NAMES sandgrouse)
add_library(http_parser http_parser.c)
add_executable(rsva11001adapter main.c rsva11001.c)
target_link_libraries(rsva11001adapter http_parser ${SANDGROUSE_LIB})
I run the following to set up the make files:
cmake --debug-output -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH="/home/ericu/localdebug" ..
Based on the CMake wiki, setting DCMAKE_PREFIX_PATH does exactly what I want.
CMAKE_PREFIX_PATH
(since CMake 2.6.0) This is used when searching for include files, binaries, or libraries using either the FIND_PACKAGE(), FIND_PATH(), FIND_PROGRAM(), or FIND_LIBRARY() commands. For each path in the CMAKE_PREFIX_PATH list, CMake will check "PATH/include" and "PATH" when FIND_PATH() is called, "PATH/bin" and "PATH" when FIND_PROGRAM() is called, and "PATH/lib" and "PATH" when FIND_LIBRARY() is called. See the documentation for FIND_PACKAGE(), FIND_LIBRARY(), FIND_PATH(), and FIND_PROGRAM() for more details.
However, when I do a 'make VERBOSE=1' this is what I get:
cd /home/ericu/rsva11001adapter/build/src && /usr/bin/gcc -std=gnu99 -g -o CMakeFiles/rsva11001adapter.dir/main.c.o -c /home/ericu/rsva11001adapter/src/main.c
/home/ericu/rsva11001adapter/src/main.c:19:31: fatal error: sandgrouse/server.h: No such file or directory
compilation terminated.
So, it does not seem that CMake is finding things in CMAKE_PREFIX_PATH. It obviously is not adding -I variables to the compiler invocations either.
An inspection of CMakeCache.txt makes it seem as though it has no idea what the variable is:
// No help, variable specified on the command line.
CMAKE_PREFIX_PATH:UNINITIALIZED=/home/ericu/localdebug
I've been working on this for over an hour. I'm nearly at the point of giving up using CMake if it is this difficult to use a non-standard library with it.
You should instruct CMake to add -I flags when compiling your library:
find_path(SANDGROUSE_INCLUDE_DIR sandgrouse/server.h)
include_directories(${SANDGROUSE_INCLUDE_DIR}
Place these lines before add_library() invocation.