dziubanmaciej / cmag Goto Github PK
View Code? Open in Web Editor NEWInteractive analyzer and browser for CMake build systems
License: MIT License
Interactive analyzer and browser for CMake build systems
License: MIT License
Currently we set x to a magic value and only increment y. Ideally we would like to arrange them in some 2D grid. We don't want a giant vertical wall of nodes.
Should this grid depend on the number of layers? It would be nice if this grid would have the same height as the layers. But if we don't have layers or we have only two, then it would look too horizontal. Some clever heuristics will be needed. We should to the screen aspect ratio - worldSpaceAspectRatio
.
The Capsaicin project is dumped correctly, but there is something wrong with graph layout. All non-orphan nodes are lumped together, probably at (0,0)
.
Source code: https://github.com/GPUOpen-LibrariesAndSDKs/Capsaicin
Sometimes ImGui expects only a const char*
as input and we have to do the format ourselves. We usually concatenate strings or allocate a temporary char array with arbitrary size and call sprintf
/snprintf
.
Goal of this task is to provide a nice helper to do this. It can be a function with a static variable with char memory allocated and call snprintf()
on it. I think snprintf
can be also called to ask for required size, so we could do this to avoid buffer overruns.
A lot of fields in the browser are held in arbitrary places, mostly in TargetGraph
class. This works, but they will not be restored after save/load. We should move them into CmagProject
class, maybe in some Graphical
sub-struct as in CmagTarget
and make json parser/writer to be aware of it.
Initial list of fields to move (may be incomplete):
struct Camera
)dependencyTypeSelected
)It would be best to do this after #32, so we can easily test if saving works.
ListDirTab
and TargetFolderTab
selectable. This should be the same selection as in TargetGraphTab
, so this state must be shared.TargetGraphTab
.It would be nice if we could double-click on a .cmag-project
file and it would launch cmag-browser. We will have to create a file association for the OS. It will require some kind of a script that runs during installation. Not sure when to remove it - we don't have a defined uninstallation routine.
On Windows we have to mess with the registry. Probably something like HKCU\SOFTWARE\Classes\.cmag-project\shell\Command = C:\Program Files\cmag\cmag_browser.exe
. Admin privileges needed.
On Linux we have to create a .desktop
file, also known as a desktop entry. They can be created in user-specific directories, so root access won't be needed.
It would be convenient to have documentation of command line options in a separate file, so we can link to it in README.
Currently it's hardcoded in argument parser classes. We could move it to a separate .txt file and generate a header file with header_pack
. Then it could be included and used by argument parser classes when -h
is passed.
We log creating various json files, but then we remove them and they are not there. Remove these logs - they are misleading.
We have an option to keep these files. We can then keep the logs as well.
Currently cmag version has 2 components. We should have 3:
1
for the most timeImplement this and document in a separate .md file. Mention that it is not semantic versioning.
Currently we don't do it, because there CMake errors on Linux.
This should always be the first step in Sugiyama layout approach. If we don't do this, we may omit some (or all) nodes during layer assignment.
This is not a very complicated algorithm (see here), but do we have to do this? Can we even have cycles? Isn't dependency graph always a DAG? It should be, but this suggests there might be an option to have cycles.
Do not show warning when FOLDER is not set to any target. If it is, check the generator:
Don't care about CMP0143. This is quite complex to reliably check and googling how it works takes 30 seconds. Let's not treat the user as a complete dumbo.
<rant>Besides, this policy seems sounds stupid... Couldn't they just change default value of USE_FOLDERS? Would be 100x simpler.</rant>
Currently we apply ellipsis if the target name is too long to fit in the node on graph.
We can enhance that and try to scale the text down before doing it, because ellipses don't look too good. So implement something like:
textWidth
na maxTextWidth
textWidth > maxTextWidth
, then scale it down by max(maxTextWidth/textWidth, threshold)
This is a continuation of #37
For single config generators, such as Unix Makefiles
we should be able to merge outputs of two cmag
analyses into a one project to be able to compare different configs.
We would have to verify all fields that are not per-config and make sure if they are the same. Some could be different, .e.g needsLayout
, in which case we would set it to true
.
Project PyTorch uses $<LINK_LANGUAGE>
generator expression, which requires special handling in dumper.
Source code: https://github.com/pytorch/pytorch
Currently we only display target's name and properties in the side pane. Show more stuff, like the type, aliases isImported
, etc.
Currently all the projects are named "project". There is an option to change it, but nobody will use it and all projects will just be called "project" forever... Use CMake project's name instead by default. This may be tricky, because we use project name in filenames, but it certainly can be done.
Not sure how the browser will behave when DPI scaling is not 100%.
Not sure what will happen when DPI changes.
I think this must be handled manually. ImGui might have some helpers. Research the topic and see what should be done.
Do this after: #69
Currently we will fail in weird ways if project file structure changes and we cannot parse the project file. A cool way would be to make the parser compatible with old formats, but that'll be too much hassle with no real benefits, at least on current stage of the project.
We need to compare version stored in project file and current cmag version. If it's different - return an error.
Currently, if a target depends on another target, but uses its alias, then we can't figure out which target it is pointing to in the preamble. CMake has ALIASED_TARGET property, but would need a reverse property - list of all aliases of a target. This is not available.
We could think of some heuristics to work out that "this target is probably an alias of that target". It could work in some cases, but sounds dangerous.
We could also create a second CMake pass. We would have to gather all targets that are listed as dependencies in LINK_LIBRARIES or MANUALLY_ADDED_DEPENDENCIES. Then feed the list to CMake (with a different postamble) and dump ALIASED_TARGET
property of all of them.
First, see how to copy to the clipboard in general. Would could do this with OS-specific APIs. We'd need to implement separately for Windows, X11 and Wayland (or not :)). Or we could use ImGui infrastructure for it. There's a function called ImGui::SetClipboardText()
. It looks like it works and should be sufficient.
In order to copy, we should have a right-click menu and an option to "Copy to clipboard". It would be good to finally create some generic helper for popups while we're at it. Maybe see BeginPopupContextItem()
instead doing popups manually?
List of data that should be copyable:
I've seen some projects fail to dump when reading super-big json files. I think it's because of how ::readFile()
function is implemented. It may truncate the output. Find the size at which this can fail, make a test for it and fix it.
Imported targets are scoped to their cmake list file only and we cannot take information about them in the postamble. This causes us to not have full information about them.
Technically we could shim additional postambles in all list files in a second cmag
pass, but that would be super complex.
We could enable CMAKE_FIND_PACKAGE_TARGETS_GLOBAL. This option could be dangerous to some projects - there could be duplicate names. Also, it is added in CMake 3.24 and we support 3.12. It would not work for all versions.
We support CMake 3.12 for cmag dumper. This is the lowest version that will work with our current postamble. It would be nice if the cmag
project itself would build with CMake 3.12.
I haven't even checked if it works. But if it's possible, we could add some CI verification to make sure we can build cmag and execute tests with CMake 3.12. I wouldn't add it to per-change testing, but we could have some way to run extra GH action on demand and verify this. For example before release.
Gather a list of popular CMake projects, clone them, run cmag on them and expect them to be parsed successfully. This will take a considerable amount of time, so it should probably be a thing to execute manually before new release or dangerous commit. It can be implemented as a GitHub action with workflow_dispatch
event.
Current list:
Do this after #57
Render MANUALLY_ADDED_DEPENDENCIES differently. Different stipple? Different color?
Make checkboxes for every dependency type instead of a combo box. User should be able to select any combination of dependency types to render.
Currently, we calculate area to check for hover based on size of the text. But this text could be shorter or longer than the table cell, so it will be wrong. Looks like it isn't that simple. Maybe we could use sizes from previous frame?
All hardcoded widths, ratios etc. used to layout the interface should be inside the theme object. We can also add a method to it to recalculate some values based on current window size. It would be called each frame or in some resize callback, if ImGui provides it.
Cmag should be easy to install on all popular supported systems. We should have:
.zip
releasesIdeally all of this should be automated, so I can release cmag on all systems at once. How to do it?
There are some generator expressions, which are evaluated differently based on the target they are bound to.
$<LINK_LANGUAGES:languages>
(required for #40)$<LINK_LANGUAGE>
$<LINK_LANG_AND_ID:language,compiler_ids>
$<COMPILE_LANGUAGE:languages>
$<COMPILE_LANGUAGE>
$<COMPILE_LANG_AND_ID:language,compiler_ids>
First problem: they cannot be be evaluated with $<TARGET_GENEX_EVAL>
. Not sure why, because it technically has all the context required, but it just doesn't work. We cannot know in advance that a property will contain one of these genexes and remove it in the postamble.
Second problem: these properties will evaluate to different values when used in INTERFACE_LINK_LIBRARIES
. Resulting value will depend on the language of target using this interface. We'll probably have to walk through all dependencies to resolve that properly.
Third problem (extension of the second): can it be transitive?
The function createGraph()
uses allDependencies
field when converting from std::vector<CmagTarget *>
to Graph
structure. We could use only the dependencies that are enabled with checkbox in the GUI to make a better graph.
Do this after #20
Saving project to json is already implemented, but not used in the browser.
Not sure how to exactly implement saving. Possible options:
Save
and Save as
. Ctrl+S shortcut to save. Would we have to implement menu bar (see BeginMenuBar()
in ImGui)? Maybe it could be somewhere else. Also, it would be good to check for changes and display the usual "Do you want to leave without saving?" dialog.To make it familiar to people, option 1. would be the best. Option 3. would be the most convenient. Maybe let's implement both and make 3. optional?
Targets can hold dependencies on custom targets using files. If a custom target has some file in OUTPUT
and some other target has it in SOURCES
than CMake will create a dependency.
Can we even check this? It may be impossible.
We have a fixed size of nodes and target names can be of arbitrary length, so there can be a situation in which they do not fit.
One solution would be to make the node width to be resizable. This would be quite complicated for rendering, graph layout algorithm and could also look weird. CMake with Graphviz does that and it doesn't look good for long names.
Another solution would be to scale down the text so it fits into the node. Not sure if this can be done. Not sure if this will look good. Fonts can be distorted.
Another solution would be to shorten the string and add ellipsis. So instead of nlohmann::json::nlohmann::json
we could see nlohmann::json:nloh...
. Full name would be displayed in a popup (on-hover).
Maybe implement 2 and 3 approaches? Scale down the text to some extent and add ellipsis if it still doesn't fit?
Define some rectangle around the edge as hover space. Display dependency types and an example invocation to show why this type is here, e.g.
Build dependency, created by
target_link_libraries(TargetA PRIVATE TargetB)
or
Manual dependency, created by
add_dependencies(TargetA TargetB)
Currently we just output them in whatever way we've ordered the targets. This works, but smarter ordering within each layer would allow us to minimize crossings.
This is a standard step for sugiyama approach, so it shouldn't be hard to find information about it. Unfortunately, it usually involves creating "virtual nodes" to eliminate edges hopping multiple layers. Cmag renders all edges as straight lines, so we'd have to think of something else.
I can't find any resources on "sugiyama layout with straight edges".
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.