Pitchfork is a Set of C++ Project Conventions

Overview

Pitchfork

Pitchfork is a set of conventions for native C and C++ projects. The most prominent being the project layout conventions.

The layout specification document is available in data/spec.bs.

Why the Name Pitchfork?

The very first public unveiling, drafting, and discussion of these project conventions started with a Reddit thread entitled "Prepare thy Pitchforks". Until that point, I had not chosen any particular name for the conventions, but I felt "Pitchfork" was as apt a name as any.

The pf Tool

This repository also hosts a (currently experimental) tool that helps you create and work with Pitchfork-compliant projects.

This project is still very young and has a while to go before being a useful developer tool. Once ready, this README will be updated with proper user documentation.

The pf Library

The pf tool mentioned above is built upon the pf library, also hosted in this repository. This library can be used to query and manipulate Pitchfork-compliant projects.

Comments
  • New subcommand: update source list from source tree

    New subcommand: update source list from source tree

    Adds a subcommand which updates a project's src/CMakeLists.txt from the source tree. Only supports CMake.

    • Automatic detection of project base-dir (for CMake).
      • Ascending filesystem iterator. Moves up a directory with each increment.
      • Use Boost::filesystem as a polyfill rather than std::experimental::filesystem
    • Edit the src/CMakeLists.txt file
    • Add an update subcommand. When the build system is specified as cmake, performs the operation.

    This inserts source files from the tree by scan the CMakeLists.txt file for function calls containing # sources comment. From that comment to the end of the function, everything is replaced with the globbed sources.

    I don't intend on this being a permanent solution. My vision is to parse the CMakeLists.txt file and use some heuristics to determine where to place the source list.

    This is very limited. It only globs for source files and header files; there's currently no option to glob for only one kind. It does skip sources directly under src/; it only grabs sources under a subdirectory of src/. It also only searches src/; it doesn't look at include/ or tests/

    The git history for this branch is kind of messy. The commits are not that clean; there may be some commits which don't build, and there are some commits which are incomplete progress

    opened by Quincunx271 8
  • Configure fails on windows at zlib2 step

    Configure fails on windows at zlib2 step

    Hello,

    I would like to evaluate pitchfork tool. Unfortunately, I can't configure it.

    I use cmake 3.14.4 and conan 1.11.1

    The configure step fails at zlib. When inspecting my folders, I see a file C:\\Users\\MartyLake\\.conan\\data\\zlib\\1.2.11\\conan\\stable\\package\\46fecbf5b55c9a04d9e1ce376246b1f9e619c3b7.dirty of size 0 instead of (I suppose?) a folder that would contain the zlib lib.

    Here is the end of cmake log:

    zlib/[email protected]/stable: 
    Calling package()
    
    ERROR: zlib/[email protected]/stable: Error in package() method, line 185
    	self._rename_libraries()
    while calling '_rename_libraries', line 133
    	os.rename(current_lib, os.path.join(lib_path, "zlib.lib"))
    	FileNotFoundError: [WinError 2] Le fichier spécifié est introuvable: 'C:\\Users\\MartyLake\\.conan\\data\\zlib\\1.2.11\\conan\\stable\\package\\46fecbf5b55c9a04d9e1ce376246b1f9e619c3b7\\lib\\zlibstatic.lib' -> 'C:\\Users\\MartyLake\\.conan\\data\\zlib\\1.2.11\\conan\\stable\\package\\46fecbf5b55c9a04d9e1ce376246b1f9e619c3b7\\lib\\zlib.lib'
    
    CMake Error at build/_pmm/1.3.1/conan.cmake:470 (message):
      Conan install failed [1]:
    
    Call Stack (most recent call first):
      build/_pmm/1.3.1/conan.cmake:495 (_pmm_conan_install_1)
      build/_pmm/1.3.1/conan.cmake:643 (_pmm_conan_install)
      build/_pmm/1.3.1/main.cmake:32 (_pmm_conan)
      build/_pmm/1.3.1/main.cmake:47 (_pmm_project_fn)
      CMakeLists.txt:32 (pmm)
    
    
    CMake Error at build/_pmm/1.3.1/conan.cmake:500 (message):
      Conan dependencies were not imported (Expected file
      C:/Users/MartyLake/Dev/pitchfork/build/conanbuildinfo.cmake).  You may need to
      run Conan manually (from the build directory).  Ensure you are using the
      'cmake' generator.
    Call Stack (most recent call first):
      build/_pmm/1.3.1/conan.cmake:643 (_pmm_conan_install)
      build/_pmm/1.3.1/main.cmake:32 (_pmm_conan)
      build/_pmm/1.3.1/main.cmake:47 (_pmm_project_fn)
      CMakeLists.txt:32 (pmm)
    
    
    CMake Error at CMakeLists.txt:33 (conan_set_find_paths):
      Unknown CMake command "conan_set_find_paths".
    
    opened by MartyLake 7
  • Test Failed: empty docs and third_party directories under tests/expected/ not included in git repository

    Test Failed: empty docs and third_party directories under tests/expected/ not included in git repository

    The tests fail with this message:

    ../../tests/generate.cpp:43
    ...............................................................................
    
    ../../tests/generate.cpp:38: FAILED:
      CHECK_FALSE( diff )
    with expansion:
      !Unexpected files in output directory:
        + docs
        + third_party
    
    ===============================================================================
    test cases: 1 | 1 failed
    assertions: 2 | 1 passed | 1 failed
    

    I'm pretty sure this is because git doesn't commit empty directories; it tracks files, not directories.

    bug 
    opened by Quincunx271 2
  • Filesystem include issue

    Filesystem include issue

    In the file src/pf/fs.hpp you differentiate between experimental and non-experimental versions of the filesystem include. I have noticed that your *else branch is wrong:

    #if STD_FS_IS_EXPERIMENTAL
    #include <experimental/filesystem>
    namespace pf {
    
    namespace fs = std::experimental::filesystem;
    
    }  // namespace pf
    #else
    #include <filesystem>
    namespace pf {
    
    namespace fs = std::experimental::filesystem;
    
    }  // namespace pf
    #endif
    

    It should be: namespace fs = std::filesystem; instead of: namespace fs = std::experimental::filesystem;

    opened by Randshot 2
  • Fix tests

    Fix tests

    Fixes #3 and fixes #8 , along with some stuff which were necessary.

    Some comments:

    • This fix for #8 is not the best code. It literally copies code from _pf_auto into a new function. Ideally, this new function would share code with _pf_auto rather than copy-paste it.
    • The ignored file is called ignore_in_diff. I don't have a preference for the name
    • The ignored file is ignored in both the expected case and actual case. It might be better to only ignore it in the expected case, just in case the actual generated directories include the ignored file.
    opened by Quincunx271 1
  • Extraneous move-from-local in return statements

    Extraneous move-from-local in return statements

    Clang caught some unneeded std::moves which inhibit copy elision:

    fs.hpp line 39

    inline std::fstream open(const fs::path& filepath, std::ios::openmode mode) {
        std::error_code ec;
        auto            ret = open(filepath, mode, ec);
        if (ec) {
            throw std::system_error{ec, "Open file: " + filepath.string()};
        }
        return std::move(ret); // error: moving a local object in a return statement prevents copy elision [-Werror,-Wpessimizing-move]
    }
    

    fs.cpp line 13

    std::fstream pf::open(const fs::path& filepath, std::ios::openmode mode, std::error_code& ec) {
        std::fstream ret;
        auto         mask = ret.exceptions() | std::ios::failbit;
        ret.exceptions(mask);
    
        try {
            ret.open(filepath.string(), mode);
        } catch (const std::ios::failure& e) {
            ec = e.code();
        }
        return std::move(ret); // error: moving a local object in a return statement prevents copy elision [-Werror,-Wpessimizing-move]
    }
    

    In both these cases, the return std::move(ret); should simply be return ret;

    bug 
    opened by Quincunx271 1
  • Allow querying into project structure info

    Allow querying into project structure info

    This is an idea for a subcommand: pf info. Pitchfork has some knowledge about the project, such as the project base directory, or potentially (in the future) the components / source files. Adding a way to query this information would be helpful for scripting.

    opened by Quincunx271 0
  • No tests were found!!!

    No tests were found!!!

    Even though the enable_testing() function is getting called by pf_auto(...), CTest cannot find any tests.

    Adding the enable_testing() call before the call to pf_auto() works, though. Adding the enable_testing() call after the call to pf_auto() does not work. This looks like a CMake bug, either in source or in documentation. It looks like the call to enable_testing() must appear before any tests are defined

    To reproduce this, make sure you start with a fresh build directory.

    opened by Quincunx271 0
  • Fix compatibility with MSVC

    Fix compatibility with MSVC

    Changes:

    • Use /permissive- for MSVC
    • Add missing #include <cctype> to mustache (https://github.com/kainjow/Mustache/issues/29)
    • Add missing #include <iterator> to tests/compare_fs.cpp
    • Changed class eof in pf.cpp to class reached_eof. MSVC complains that eof is ambiguous at catch (const eof&)
    opened by Quincunx271 0
  • Use conan for Catch2

    Use conan for Catch2

    Installing conan is pip install --user conan (I like the --user flag; without it I think you need sudo)

    To use this:

    $ cd build
    $ conan install ..
    $ cmake -DCMAKE_PROJECT_pitchfork_INCLUDE=$(pwd)/conan_paths.cmake ..
    

    For conan packages which don't properly support non-intrusive cmake integration, it's a bit more work (I write a custom cmake include file that wraps find_package)

    opened by Quincunx271 0
  • Where to place source of other languages

    Where to place source of other languages

    Hello, I have a "big" project with mostly C++, but also some python files!

    The spec says src is for compilable source (and I wouldnt want to put rogue python files in there anyway), but what would be the best place then? My best guess and what I did until now is a python folder in root basically acting like a src folder.

    A similar issue I have now is for packaging. Multiple CMake files could go in a cmake folder. What about deb's control, postinst etc (those are basically package specs: dependencies, things to do on install etc), a debian folder maybe ?

    It did make sense for python but now I feel like this is getting out of hand 😅

    opened by kiwixz 1
  • where to put source files for PGO training programs

    where to put source files for PGO training programs

    I have a library (a submodule under libs/) that I want to build with profile-guided optimization. To run the instrumented library to collect profile data, I plan to make a setup where I can choose from multiple small-ish training programs which call functions from the library. Where is a good place to put the source code for the training programs?

    • They definitely aren't "source code" in the sense of implementing any functionality of the library.
    • They aren't tests because they don't have anything to do with checking the correctness of the code.
    • They don't seem quite like "extras" since the library is the core part of the project, and the training programs are an essential part of its build process when doing PGO.
    • They definitely aren't data, but they are used to produce data (which shouldn't be checking into version control)
    • I do have an apps/ directory as discussed as one option in #30, but PGO training programs just don't feel like "apps" to me. They aren't useful or intended for anything except gathering representative profile data.

    I'd like to hear what the authors of this spec think: Would it be "wrong" of me to add a new child directory inside the library's submodule directory just for pgo training program source code?

    opened by david-fong 0
  • Managing multiple libraries

    Managing multiple libraries

    PFL doesn't address the integration of multiple libraries in one project. The document below offers a possible solution. The Dogfood and the Pitchfork.md

    Thank you for taking the time to consider it.

    opened by neacsum 2
  • If platform bindings go into `extras/` then extras aren't really

    If platform bindings go into `extras/` then extras aren't really "built upon" the main component(s)

    w.r.t. the first paragraph of 4.4 extras/:

    I get why platform bindings are not in libs/ as they're not always built and that's a requirement for the submodules in libs/. (Some people may never build the Windows bindings, others never build the Linux bindings ...) But typically one or another of them is always required for any given build. They're at the foundation of the project.

    So I'm fine with them in extras but the wording of what goes in extras should be changed ...

    Or maybe it's the requirement that stuff in libs/ is always built that should be relaxed ...

    But actually, in my own project, I'm putting them as submodules in libs/.

    (In fact, I have added another layer inside of libs/ where I group submodules by "category" - I may have multiple implementations of a given service interface, for example, so I put them together under, say, "storage" (one submodule for sqlite, one for filesystem, one for webdav, ...) - and in this way I'll have libs/platform/ and there will be under it windows and linux (macos can go into extras/ with any other contributed stuff...).)

    (Pitchfork is well thought-out IMO, thanks for the effort!)

    opened by david-bakin 0
  • I am uncomfortable with the inconsistency of sometimes having a /src/ folder and sometimes not.

    I am uncomfortable with the inconsistency of sometimes having a /src/ folder and sometimes not.

    If a project with submodules is a directed graph, thus requiring all submodules to be siblings, then simply put all submodules in folders under the /src/ subfolder. For consistency, always place the main submodule in /src/main/, and place the other submodules in their own folders as sibling folders to /main/. If submodules are actually useful as separate libraries, then place them into subfolders of /lib/ and treat /lib/ with the rules currently ascribed to /external/. This, then, makes /external/ redundant, so it can be eliminated.

    When most people think of "Libs" they think of "external libraries." However, within the context of Pitchfork," "Libs" takes on a different meaning, as "private submodules used only within the current project." This is also inconsistent.

    The above suggestion does not take into consideration the debate as to whether external libraries should even be copied to the project folder. If it is decided that external libraries should not be copied to the project folder, the /lib/ folder could be used to hold simlinks to the original folders for those libraries, OR the /lib/ folder could also be eliminated and proper makefiles could be constructed to point to where the external libraries are stored.

    Note: I am also using the singular version for all these folder names.

    opened by GrantRobertson 3
Owner
null
Starter project for cross platform WebGPU development in C++

A starter code for cross-platform (i.e., web & native) C++ WebGPU projects.

Will Usher 30 Dec 7, 2022
Best practices, conventions, and tricks for ROS. Do you want to become a robotics master? Then consider graduating or working at the Robotics Systems Lab at ETH in Zürich!

ROS Best Practices, Conventions and Tricks Best practices for ROS2 in the making. See the Foxy branch in the meanwhile. This is a loose collection of

Robotic Systems Lab - Legged Robotics at ETH Zürich 1.2k Jan 5, 2023
Implementation of Univaraint Linear Regresion (Supervised Machine Learning) in c++. With a data set (training set) you can predict outcomes.

Linear-Regression Implementation of Univaraint Linear Regresion (Supervised Machine Learning) in c++. With a data set (training set) you can predict o

vincent laizer 1 Nov 3, 2021
oZKS (Ordered Zero-Knowledge Set) is a library that provides an implementation of an Ordered (and Append Only) Zero-Knowledge Set.

Ordered Zero-Knowledge Set - oZKS Introduction oZKS is a library that provides an implementation of an Ordered (and Append Only) Zero Knowledge Set. A

Microsoft 11 Dec 20, 2022
6D - Pose Annotation Tool (6D-PAT) - is a tool that allows the user to load a set of images and also a set of 3D models and annotate where in the 2D image the 3D object ist placed.

6D - Pose Annotation Tool (6D-PAT) For detiled explanations checkout the WikiPage. What is it? With 6D-PAT you can create 6D annotations on images for

Florian Blume 71 Nov 20, 2022
This is a beginner-friendly project aiming to build a problem-set on different data structures and algorithms in different programming languages.

DSAready Overview This is a beginner-friendly project that aims to create a problem-set for various Data Structures and Algorithms. Being a programmer

Riddhi Jain 13 Aug 17, 2022
Basic Development Environment - a set of foundational C++ libraries used at Bloomberg.

BDE Libraries This repository contains the BDE libraries, currently BSL (Basic Standard Library), BDL (Basic Development Library), BAL (Basic Applicat

Bloomberg 1.4k Dec 29, 2022
CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.

CLI11: Command line parser for C++11 What's new • Documentation • API Reference CLI11 is a command line parser for C++11 and beyond that provides a ri

null 2.4k Dec 30, 2022
C++ implementation of a fast hash map and hash set using hopscotch hashing

A C++ implementation of a fast hash map and hash set using hopscotch hashing The hopscotch-map library is a C++ implementation of a fast hash map and

Thibaut Goetghebuer-Planchon 578 Dec 23, 2022
C++ implementation of a fast hash map and hash set using robin hood hashing

A C++ implementation of a fast hash map and hash set using robin hood hashing The robin-map library is a C++ implementation of a fast hash map and has

Thibaut Goetghebuer-Planchon 872 Dec 26, 2022
Wangle is a framework providing a set of common client/server abstractions for building services in a consistent, modular, and composable way.

Wangle C++ networking library Wangle is a library that makes it easy to build protocols, application clients, and application servers. It's like Netty

Facebook 2.9k Jan 8, 2023
The C++ Core Guidelines are a set of tried-and-true guidelines, rules, and best practices about coding in C++

The C++ Core Guidelines are a collaborative effort led by Bjarne Stroustrup, much like the C++ language itself. They are the result of many person-years of discussion and design across a number of organizations. Their design encourages general applicability and broad adoption but they can be freely copied and modified to meet your organization's needs.

Standard C++ Foundation 36.6k Jan 6, 2023
The libxo library allows an application to generate text, XML, JSON, and HTML output using a common set of function calls. The application decides at run time which output style should be produced.

libxo libxo - A Library for Generating Text, XML, JSON, and HTML Output The libxo library allows an application to generate text, XML, JSON, and HTML

Juniper Networks 253 Dec 10, 2022
Mystikos is a set of tools for running applications in a hardware trusted execution environment (TEE)

Mystikos is a set of tools for running applications in a hardware trusted execution environment (TEE). The current release supports Intel ® SGX while other TEEs may be supported in future releases. Linux is also a supported target, though only suitable for testing purposes as it provides no additional protection.

null 116 Dec 14, 2022
A virtual processor with a unique instruction set written in C++

Processor-Project A virtual processor with an instruction set similar to ARM made in C++. How it works This virtual processor allows the user to write

null 20 May 27, 2022
the checkra1n set of tools targeting bare metal, Linux and Windows

Universal toolchain Low-effort cross-compiling for the masses. What's Universal toolchain? It's a collection of sysroots and shell scripts in such a w

null 67 Jan 5, 2023
A set of libraries and tools to make MSX games using the C programming language.

ubox MSX lib This is a set of libraries and tools to make MSX games using the C programming language. There are three main components: ubox: thin wrap

Juan J. Martínez 42 May 30, 2022
Set of pre-generated pwn.college challenges

pwn.college Set of pre-generated pwn.college challenges! Setup Replace <INSTANCE> with your instance's name: ./generate_sql.sh | docker exec -i <INSTA

pwn.college 49 Dec 12, 2022
A guide and set of tools for working with TinyML powered Audio Sensors

Audio Sensor Toolkit This is a guide on how to build an Audio Sensor using Machine Learning, and helpful tools. Audio Sensor Guide Audio Tools Acceler

IQT Labs 20 Sep 21, 2022