├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── README.md ├── cdbConfig.cmake ├── debian ├── changelog ├── compat ├── control ├── copyright ├── rules └── source │ └── format ├── include └── cdb │ └── cdb.h ├── publish_to_ppa.sh ├── src ├── cdb.cpp ├── main.cpp └── test_cdb.cpp ├── test.sh └── test └── CMakeLists.txt /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | cmake-build-debug 3 | .idea 4 | debian/files 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c++ 2 | 3 | os: linux 4 | dist: bionic 5 | install: 6 | - sudo apt-get install --yes libreadline7 cmake catch 7 | compiler: g++ 8 | 9 | script: mkdir build && cd build && cmake -DCMAKE_VERBOSE_MAKEFILE=ON .. && make && ctest 10 | 11 | after_success: 12 | - cd ~/build/nbelakovski/cdb 13 | - bash <(curl -s https://codecov.io/bash) 14 | 15 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | project(cdb) 3 | 4 | add_library(${PROJECT_NAME}_lib src/cdb.cpp) 5 | target_include_directories(${PROJECT_NAME}_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) 6 | target_compile_features(${PROJECT_NAME}_lib PUBLIC cxx_std_11) 7 | target_compile_options(${PROJECT_NAME}_lib PUBLIC --coverage) 8 | target_link_libraries(${PROJECT_NAME}_lib PUBLIC gcov) 9 | 10 | add_executable(${PROJECT_NAME} src/main.cpp) 11 | 12 | target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_lib readline) 13 | 14 | ## Installation 15 | install(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin/) 16 | install(FILES cdbConfig.cmake DESTINATION /usr/share/cmake/cdb/) 17 | 18 | ## Testing 19 | enable_testing() 20 | add_test(NAME ${PROJECT_NAME}_integration_test COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/test.sh") 21 | 22 | add_executable(${PROJECT_NAME}_unit_test src/test_cdb.cpp) 23 | target_link_libraries(${PROJECT_NAME}_unit_test PUBLIC ${PROJECT_NAME}_lib) 24 | add_test(NAME ${PROJECT_NAME}_unit_test_runner COMMAND 25 | ${PROJECT_NAME}_unit_test) 26 | 27 | ## Packaging 28 | # SET(CPACK_GENERATOR "DEB") 29 | # set(CPACK_PACKAGE_NAME cdb) 30 | # SET(CPACK_PACKAGE_CONTACT "Nickolai Belakovski") 31 | # SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") 32 | # SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libgcc1, libreadline7, libstdc++6") 33 | # set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A debugger for CMake files") 34 | 35 | # SET(CPACK_PACKAGE_VERSION_MAJOR "0") 36 | # SET(CPACK_PACKAGE_VERSION_MINOR "1") 37 | # SET(CPACK_PACKAGE_VERSION_PATCH "0") 38 | 39 | # INCLUDE(CPack) 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.com/nbelakovski/cdb.svg?branch=master)](https://travis-ci.com/nbelakovski/cdb) [![codecov](https://codecov.io/gh/nbelakovski/cdb/branch/master/graph/badge.svg)](https://codecov.io/gh/nbelakovski/cdb) 2 | ## Installation 3 | 4 | From PPA 5 | ``` 6 | sudo add-apt-repository ppa:nbelakovski/cdb 7 | sudo apt-get update 8 | sudo apt-get install cdb 9 | ``` 10 | 11 | From source 12 | ``` 13 | git clone https://github.com/nbelakovski/cdb.git 14 | cd cdb 15 | mkdir build 16 | cd build 17 | cmake .. 18 | make 19 | sudo make install 20 | ``` 21 | 22 | This will install just two files, `/usr/bin/cdb` and `/usr/share/cmake/cdb/cdbConfig.cmake` 23 | 24 | ## Usage 25 | 26 | In a CMakeLists.txt file, add 27 | 28 | `find_package(cdb)` 29 | 30 | and then call the break function anywhere you want to stop executation and examine the environment 31 | 32 | `break()` 33 | 34 | You can see an example in the test/ folder. 35 | 36 | `break()` will take all of the cmake variables active in the current context and pass them to the cdb program which 37 | will let you examine them. Exiting from that examination will continue the cmake process. 38 | 39 | To list all variables currently known, type `dump` 40 | 41 | ``` 42 | ) dump 43 | CMAKE_AR=/usr/bin/ar 44 | CMAKE_AUTOMOC_COMPILER_PREDEFINES=ON 45 | CMAKE_AUTOMOC_MACRO_NAMES=Q_OBJECT 46 | CMAKE_BASE_NAME=g++ 47 | ... 48 | ``` 49 | 50 | To get the value of a particular variable, use ${var} 51 | 52 | ``` 53 | ) ${CMAKE_AR} 54 | /usr/bin/ar 55 | ) ${CMAKE_ARC} 56 | CMAKE_ARC not found 57 | ``` 58 | 59 | ## Notes 60 | 61 | This is a pretty basic debugger. All it can do is show you some CMake variables, get some target properties*, and help you evaluate some if statements*. 62 | 63 | It will need a pretty sincere overhaul to work more closely with CMake internals if it will ever get to the point where you'll be able to set variables, step through execution, etc. 64 | 65 | 66 | \* Coming in a future release 67 | -------------------------------------------------------------------------------- /cdbConfig.cmake: -------------------------------------------------------------------------------- 1 | 2 | find_program(cdb cdb /usr/bin ${CMAKE_CURRENT_SOURCE_DIR}/build) 3 | 4 | function(break) 5 | get_cmake_property(_variableNames VARIABLES) 6 | list (SORT _variableNames) 7 | foreach (_variableName ${_variableNames}) 8 | list(APPEND vars "${_variableName}=${${_variableName}}") 9 | endforeach() 10 | execute_process(COMMAND bash "-c" "${cdb} '${vars}'") 11 | endfunction() 12 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | cdb (0.1.4) bionic; urgency=medium 2 | 3 | * Rely on system installed catch instead of having it in the repo 4 | * Add build dependency on libreadline-dev 5 | 6 | -- Nickolai Belakovski Wed, 01 Jan 2020 22:55:24 -0800 7 | 8 | cdb (0.1.3) bionic; urgency=medium 9 | 10 | * Switching to catch from gtest since its header only 11 | 12 | -- Nickolai Belakovski Wed, 01 Jan 2020 22:46:23 -0800 13 | 14 | cdb (0.1.2) bionic; urgency=medium 15 | 16 | * Fix issue with depending on readline6 instead of 7 17 | 18 | -- Nickolai Belakovski Wed, 01 Jan 2020 22:22:09 -0800 19 | 20 | cdb (0.1.1) bionic; urgency=medium 21 | 22 | * 23 | 24 | -- Nickolai Belakovski Wed, 01 Jan 2020 22:02:00 -0800 25 | 26 | cdb (0.1.0) bionic; urgency=medium 27 | 28 | * Initial Release. 29 | 30 | -- Nickolai Belakovski Wed, 01 Jan 2020 18:44:50 -0800 31 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: cdb 2 | Section: devel 3 | Priority: optional 4 | Maintainer: Nickolai Belakovski 5 | Build-Depends: debhelper (>= 10), libreadline7, cmake, catch, libreadline-dev 6 | Standards-Version: 4.1.2 7 | Vcs-Git: https://github.com/nbelakovski/cdb.git 8 | 9 | Package: cdb 10 | Architecture: any 11 | Depends: ${shlibs:Depends}, ${misc:Depends}, libgcc1, libreadline7, libstdc++6 12 | Description: A debugger for CMake files 13 | Simple for now, with great ambitions 14 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: cdb 3 | Source: 4 | 5 | Files: * 6 | Copyright: 2020 Nickolai Belakovski 7 | License: Apache-2.0 8 | 9 | Files: debian/* 10 | Copyright: 2020 Nickolai Belakovski 11 | License: Apache-2.0 12 | 13 | License: Apache-2.0 14 | Licensed under the Apache License, Version 2.0 (the "License"); 15 | you may not use this file except in compliance with the License. 16 | You may obtain a copy of the License at 17 | . 18 | https://www.apache.org/licenses/LICENSE-2.0 19 | . 20 | Unless required by applicable law or agreed to in writing, software 21 | distributed under the License is distributed on an "AS IS" BASIS, 22 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | See the License for the specific language governing permissions and 24 | limitations under the License. 25 | . 26 | On Debian systems, the complete text of the Apache version 2.0 license 27 | can be found in "/usr/share/common-licenses/Apache-2.0". 28 | 29 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ 5 | 6 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /include/cdb/cdb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace cdb 6 | { 7 | 8 | std::map extract_vars(const std::string &vars); 9 | 10 | } // close namespace cdb 11 | -------------------------------------------------------------------------------- /publish_to_ppa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is meant to be run manually 4 | 5 | set -ex 6 | 7 | cd "$( dirname "${BASH_SOURCE[0]}" )" 8 | 9 | git clean -xffd 10 | rm -rf ../cdb_* 11 | debuild -S -sa 12 | VERSION=$(head -1 debian/changelog | awk '{print $2}' | sed 's/[()]//g') 13 | dput ppa:nbelakovski/cdb ../cdb_${VERSION}_source.changes 14 | 15 | -------------------------------------------------------------------------------- /src/cdb.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace cdb 4 | { 5 | 6 | std::map extract_vars(const std::string &vars) 7 | { 8 | size_t index = 0; 9 | std::map varvals; 10 | size_t pos = 0; 11 | while((pos = vars.find(';', index)) != std::string::npos) 12 | { 13 | const std::string varval = vars.substr(index, pos - index); 14 | index = pos+1; 15 | // now split on '=' 16 | int pos2 = varval.find('='); 17 | const std::string var = varval.substr(0, pos2); 18 | const std::string val = varval.substr(pos2 + 1); 19 | varvals[var] = val; 20 | } 21 | // last one 22 | { 23 | const std::string varval = vars.substr(index); 24 | // now split on '=' 25 | int pos2 = varval.find('='); 26 | const std::string var = varval.substr(0, pos2); 27 | const std::string val = varval.substr(pos2 + 1); 28 | varvals[var] = val; 29 | } 30 | return varvals; 31 | } 32 | 33 | } // close namespace cdb 34 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | int main (int argc, char * argv[]) 11 | { 12 | // the first arg is of the form var1=value1;var2=value2, so we need to 13 | // split by ';', and then split again by '=' and generate a map of var-value pairs 14 | std::map varvals = cdb::extract_vars(std::string(argv[1])); 15 | 16 | char * line = nullptr; 17 | const std::string history_filename = std::string(getenv("HOME")) + "/.cdb_history"; 18 | (void) read_history(history_filename.c_str()); 19 | std::cout << "Type ?, h, or help for a list of available commands" << std::endl; 20 | while( (line = readline(") ")) ) 21 | { 22 | add_history(line); 23 | std::string command(line); // put it in an std::string for convenience 24 | free(line); 25 | line = nullptr; 26 | if(command == "exit" || command == "quit") 27 | { 28 | break; 29 | } 30 | else if(command == "dump") 31 | { 32 | for(const auto & pair : varvals) 33 | { 34 | std::cout << pair.first << "=" << pair.second << std::endl; 35 | } 36 | } 37 | else if(command == "help" || command == "?" || command == "h") 38 | { 39 | std::cout << "dump - print out all variables and their values" << std::endl; 40 | std::cout << "exit - exits the program. Can also be accomplished with 'quit' and Ctrl + D" << std::endl; 41 | std::cout << "${var} - prints out the value of var. If var does not exist, prints 'var not found'" << std::endl; 42 | } 43 | else 44 | { 45 | size_t open_brace_pos = command.find("${"); 46 | size_t close_brace_pos = command.find('}'); 47 | const std::string var = command.substr(open_brace_pos + 2, close_brace_pos - open_brace_pos - 2); 48 | if (varvals.find(var) != varvals.end()) { 49 | std::cout << varvals[var] << std::endl; 50 | } else { 51 | std::cout << var << " not found" << std::endl; 52 | } 53 | } 54 | } 55 | (void) write_history(history_filename.c_str()); 56 | return 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/test_cdb.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file 3 | #include 4 | 5 | 6 | TEST_CASE("cdb", "ExtractVars") 7 | { 8 | const std::string vars("abc=123;t=;f=a"); 9 | std::map varvals = cdb::extract_vars(vars); 10 | REQUIRE(varvals.size() == 3); 11 | REQUIRE(varvals["abc"] == "123"); 12 | REQUIRE(varvals["t"] == ""); 13 | REQUIRE(varvals["f"] == "a"); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | cd "$( dirname "${BASH_SOURCE[0]}" )" 6 | 7 | cd test 8 | mkdir build 9 | cd build 10 | echo "exit" | cmake .. 11 | echo "help" | cmake .. 12 | echo "dump" | cmake .. 13 | echo '${CMAKE_AR}' | cmake .. 14 | echo '${CMAKE_ARC}' | cmake .. 15 | 16 | # cleanup 17 | cd .. 18 | rm -rf build 19 | 20 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | project(test) 3 | 4 | set(cdb_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) 5 | # find cdb program before the find_package call 6 | # while this means we don't test the find_program part, it also means we don't need sudo access on a machine 7 | # in order to test 8 | find_program(cdb cdb ${CMAKE_CURRENT_SOURCE_DIR}/../build) 9 | find_package(cdb) 10 | 11 | break() 12 | 13 | --------------------------------------------------------------------------------