diff --git a/.github/workflows/ubuntu_latest.yml b/.github/workflows/ubuntu_latest.yml index 033ad7f..5e6bc75 100644 --- a/.github/workflows/ubuntu_latest.yml +++ b/.github/workflows/ubuntu_latest.yml @@ -6,16 +6,20 @@ on: pull_request: branches: [ master ] +env: + CURL_GET: curl -fL --retry 3 --retry-delay 2 + PATH_GET: https://github.com/mkn/mkn/releases/download/latest + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v6 - run: sudo apt-get install iwyu - run: | - curl -Lo mkn https://github.com/mkn/mkn/releases/download/latest/mkn_nix + $CURL_GET -o mkn ${PATH_GET}/mkn_nix chmod +x mkn - KLOG=3 ./mkn clean build -dtOp iwyu -a "-std=c++17 -fPIC" + KLOG=3 ./mkn clean build -dtOp iwyu -a "-std=c++20 -fPIC" diff --git a/.gitignore b/.gitignore index 34d04f5..ef5af5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ bin .mkn +.clangd diff --git a/.sublime-project b/.sublime-project index 7ae0fc0..aee86ad 100644 --- a/.sublime-project +++ b/.sublime-project @@ -7,6 +7,12 @@ ], "settings": { + "ClangFormat" : + { + "binary" : "clang-format", + "format_on_save" : true, + "style" : "file" + } } } diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7616ede..0000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -language: generic -branches: - only: - - master -matrix: - include: - - os: linux - dist: bionic - sudo: required - compiler: gcc - addons: - apt: - sources: - - sourceline: 'ppa:ubuntu-toolchain-r/test' - packages: - - g++-8 - - clang++-8 - - iwyu - env: - - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" - - os: osx - compiler: clang - osx_image: xcode11 - -before_install: - - | - git clone https://github.com/Dekken/maiken --depth 10 -b master maiken - [[ "${TRAVIS_OS_NAME}" == "osx" ]] && make bsd -C maiken CXX="clang++" - [[ "${TRAVIS_OS_NAME}" == "linux" ]] && eval "${MATRIX_EVAL}" - [[ "${TRAVIS_OS_NAME}" == "linux" ]] && make nix -C maiken CXX="$CXX" - mv maiken/mkn . - -script: - - | - export MKN_LIB_LINK_LIB="1" KUL_GIT_CO="--depth 3" KLOG="3" CC CXX - ./mkn build -dtOa "-fPIC -std=c++17" - ./mkn build -p iwyu diff --git a/README.md b/README.md index 8f745d4..4b8582c 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,8 @@ ** Compile stage plugin to to run include-what-you-use on all applicable files ** -[![Travis](https://travis-ci.org/mkn-mod/cpp.iwyu.svg?branch=master)](https://travis-ci.org/mkn-mod/cpp.iwyu) - ## Prerequisites - [maiken](https://github.com/Dekken/maiken) + [maiken](https://github.com/mkn/mkn) ## Usage @@ -18,8 +16,7 @@ mod: inc: inc/1 inc/2 # additional include directories paths: search/dir # scan directories ignore: src/python3 # if file found has path that contains string ignore - - + types: cpp hpp cc # file types checked default: {"cpp", "cxx", "cc", "cc", "h", "hpp"} ``` diff --git a/mkn.yaml b/mkn.yaml index ac2ec0c..a734786 100644 --- a/mkn.yaml +++ b/mkn.yaml @@ -11,10 +11,10 @@ mode: shared profile: - name: base - dep: mkn#${version}&${maiken_location}(${maiken_scm})[mod] + dep: mkn.mod mkn#${version}&${maiken_location}(${maiken_scm})[headers] if_arg: win_shared: -DYAML_CPP_DLL - shared: -DKUL_SHARED + shared: -DMKN_KUL_SHARED - name: format mod: | diff --git a/mod.cpp b/mod.cpp index ad7f717..9c33eec 100644 --- a/mod.cpp +++ b/mod.cpp @@ -1,5 +1,5 @@ /** -Copyright (c) 2013, Philip Deegan. +Copyright (c) 2026, Philip Deegan. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -28,101 +28,92 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "mkn/mod/init.hpp" // IWYU pragma: keep + #include // for uint16_t #include // for string, allocator, operator+, basic_... #include // for unordered_set #include // for pair #include // for vector -#include "mkn/kul/cli.hpp" // for asArgs -#include "mkn/kul/defs.hpp" // for KUL_PUBLISH -#include "mkn/kul/except.hpp" // for Exception, KEXCEPT, KTHROW -#include "mkn/kul/log.hpp" // for KLOG, KLOG_INF, KLOG_DBG -#include "mkn/kul/map.hpp" // for Map -#include "mkn/kul/os.hpp" // for Dir, File, WHICH, Exception, PushDir -#include "mkn/kul/proc.hpp" // for Process, AProcess, ExitException -#include "mkn/kul/string.hpp" // for String -#include "mkn/kul/yaml.hpp" // for NodeValidator, Validator, yaml -#include "maiken/app.hpp" // for Application -#include "maiken/module.hpp" // for Module -#include "maiken/module/init.hpp"// IWYU pragma: keep -#include "maiken/project.hpp" // for Project -#include "maiken/source.hpp" // for Source +#include "mkn/kul/cli.hpp" // for asArgs +#include "mkn/kul/defs.hpp" // for MKN_KUL_PUBLISH +#include "mkn/kul/except.hpp" // for Exception, KEXCEPT, KTHROW +#include "mkn/kul/log.hpp" // for KLOG, KLOG_INF, KLOG_DBG +#include "mkn/kul/map.hpp" // for Map +#include "mkn/kul/os.hpp" // for Dir, File, WHICH, Exception, PushDir +#include "mkn/kul/proc.hpp" // for Process, AProcess, ExitException +#include "mkn/kul/string.hpp" // for String +#include "mkn/kul/yaml.hpp" // for NodeValidator, Validator, yaml #include "yaml-cpp/node/impl.h" // for Node::operator[], Node::Scalar #include "yaml-cpp/node/node.h" // for Node -namespace mkn::mod::iwyu { +namespace mkn::mod::cpp::iwyu { -class Exception : public mkn::kul::Exception { +class Module : public mkn::mod::Module { public: - Exception(char const* f, uint16_t const& l, std::string const& s) - : mkn::kul::Exception(f, l, s) {} -}; -} - -namespace mkn { - -class CPP_IWYU_Module : public maiken::Module { - public: - void compile(maiken::Application& a, YAML::Node const& node) KTHROW(std::exception) override { - run(a, node); - } + void compile(mkn::mod::Context& ctx, YAML::Node const& node) override { run(ctx, node); } protected: - using App = maiken::Application&; - - static std::string find_iwyu(){ + static std::string find_iwyu() { std::vector iwyu{"iwyu", "include-what-you-use"}; - for(auto const& str : iwyu) - if(mkn::kul::env::WHICH(str)) return str; - KEXCEPT(mkn::mod::iwyu::Exception, "Failed to find valid iwyu binary, check PATH"); + for (auto const& str : iwyu) + if (kul::env::WHICH(str)) return str; + KEXCEPT(Exception, "Failed to find valid iwyu binary, check PATH"); } static void VALIDATE_NODE(YAML::Node const& node) { - using namespace mkn::kul::yaml; + using namespace kul::yaml; Validator({NodeValidator("inc"), NodeValidator("args"), NodeValidator("ignore"), - NodeValidator("headers"), - NodeValidator("paths"), NodeValidator("types")}) + NodeValidator("headers"), NodeValidator("paths"), NodeValidator("types")}) .validate(node); } - template - void CHECK(std::string const& proc, C_Unit c_unit, mkn::kul::File&& f, YAML::Node const& node) { - if (node["ignore"]) if(f.escm().find(node["ignore"].Scalar()) != std::string::npos) return; + void CHECK(std::string const& proc, std::string const& compileCmd, kul::File&& f, + YAML::Node const& node) { + if (node["ignore"]) + if (f.escm().find(node["ignore"].Scalar()) != std::string::npos) return; - mkn::kul::Process p(proc); - auto compileStr = c_unit.compileString().substr(c_unit.compiler.size()); + kul::Process p(proc); + auto const firstSpace = compileCmd.find(' '); + auto compileStr = + firstSpace == std::string::npos ? std::string() : compileCmd.substr(firstSpace + 1); p << compileStr.substr(0, compileStr.rfind(" -o")); if (node["args"]) p << node["args"].Scalar(); - if (node["inc"]) for (const auto& inc : node["inc"].Scalar()) p << std::string{"-I"}+inc; + if (node["inc"]) + for (const auto& inc : mkn::kul::cli::asArgs(node["inc"].Scalar())) + p << std::string{"-I"} + inc; if (node["headers"]) p << node["headers"].Scalar(); p << f.escm(); KLOG(DBG) << p; - try{ + try { p.start(); - }catch(mkn::kul::proc::ExitException const& e){} + } catch (kul::proc::ExitException const& e) { + } } - void run(App& a, YAML::Node const& node) KTHROW(std::exception) { + void run(mkn::mod::Context& ctx, YAML::Node const& node) KTHROW(std::exception) { VALIDATE_NODE(node); - mkn::kul::os::PushDir pushd(a.project().dir()); + auto const state = ctx.state(); + kul::os::PushDir pushd(state.projectDir); std::unordered_set types; if (!node["types"]) { types = {"cpp", "cxx", "cc", "cc", "h", "hpp"}; } else - for (const auto& s : mkn::kul::String::SPLIT(node["types"].Scalar(), ":")) types.insert(s); + for (const auto& s : kul::String::SPLIT(node["types"].Scalar(), ":")) types.insert(s); std::unordered_set files; - const auto sources = a.sourceMap(); - for (const auto& p1 : sources) - if (types.count(p1.first)) - for (const auto& p2 : p1.second) - for (const auto& p3 : p2.second) files.insert(p3.in()); + for (const auto& f : state.sourceFiles) { + auto const dot = f.rfind("."); + if (dot == std::string::npos) continue; + if (types.count(f.substr(dot + 1))) files.insert(f); + } - if (node["paths"]){ - for (const auto& path : mkn::kul::cli::asArgs(node["paths"].Scalar())) { - mkn::kul::Dir d(path); - if (!d) KEXCEPT(mkn::kul::fs::Exception, "Directory does not exist: ") << d.path(); + if (node["paths"]) { + for (const auto& path : kul::cli::asArgs(node["paths"].Scalar())) { + kul::Dir d(path); + if (!d) KEXCEPT(kul::fs::Exception, "Directory does not exist: ", d.path()); for (const auto& file : d.files(1)) { const std::string name = file.name(); if (name.find(".") == std::string::npos) continue; @@ -133,17 +124,15 @@ class CPP_IWYU_Module : public maiken::Module { } auto proc = find_iwyu(); - maiken::ThreadingCompiler tc(a); - using Pair = std::pair; for (const auto& file : files) - CHECK(proc, tc.compilationUnit(Pair{mkn::kul::File(file).escm()+".cpp", "obj"}), mkn::kul::File(file), node); + CHECK(proc, ctx.compileCommandFor(kul::File(file).escm() + ".cpp"), kul::File(file), node); } }; -} // namespace mkn +} // namespace mkn::mod::cpp::iwyu -extern "C" KUL_PUBLISH maiken::Module *maiken_module_construct() { - return new mkn::CPP_IWYU_Module; +extern "C" MKN_KUL_PUBLISH mkn::mod::Module* maiken_module_construct() { + return new mkn::mod::cpp::iwyu::Module; } -extern "C" KUL_PUBLISH void maiken_module_destruct(maiken::Module *p) { delete p; } +extern "C" MKN_KUL_PUBLISH void maiken_module_destruct(mkn::mod::Module* p) { delete p; }