360 Secure SkillHub
360 安全技能中心

Build ROSE tools using a container

核心功能:提供预配置ROSE及对应工具链的容器环境,强制使用Makefile构建,支持并行编译、测试,确保构建一致性。典型场景:开发源码转译、调用图分析、AST处理等依赖librose.so的工具。输入为用户的ROSE工具代码与规范Makefile,输出为可执行工具及运行结果,解决现代主机无ROSE所需旧版依赖的问题。

chunhualiao
chunhualiao
热度 67.80
最近更新 2026-05-11 16:27:50
分类:开发依赖:纯提示词应用场景:代码生成 / 调试排错 / DevOps

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add rose-container-tools
Metadata
name
rose-container-tools
version
0.1.0
description
Build and run ROSE compiler tools using ROSE installed in a Docker container. Use when developing source-to-source translators, call graph analyzers, AST processors, or any tool that links against librose.so. Triggers on "ROSE tool", "callgraph", "AST traversal", "source-to-source", "build with ROSE", "librose".

ROSE Container Tools

Build and run ROSE-based source code analysis tools using ROSE installed in a container.

⚠️ ALWAYS Use Makefile

Never use ad-hoc scripts or command-line compilation for ROSE tools.

  • Use Makefile for all builds
  • Enables make -j parallelism
  • Ensures consistent flags
  • Supports make check for testing

Why Container?

ROSE requires GCC 7-10 and specific Boost versions. Most modern hosts don't have these. The container provides:

  • Pre-installed ROSE at /rose/install
  • Correct compiler toolchain
  • All dependencies configured

Quick Start

1. Start the Container

# If container exists
docker start rose-tools-dev
docker exec -it rose-tools-dev bash

# Or create new container
docker run -it --name rose-tools-dev \
  -v /home/liao/rose-install:/rose/install:ro \
  -v $(pwd):/work \
  -w /work \
  rose-dev:latest bash

2. Build with Makefile

Always use Makefile to build ROSE tools. Never use ad-hoc scripts.

# Inside container
make        # Build all tools
make check  # Build and test

3. Run the Tool

./build/my_tool -c input.c

Makefile (Required)

Create Makefile for your tool:

ROSE_INSTALL = /rose/install

CXX      = g++
CXXFLAGS = -std=c++14 -Wall -g -I$(ROSE_INSTALL)/include/rose
LDFLAGS  = -L$(ROSE_INSTALL)/lib -Wl,-rpath,$(ROSE_INSTALL)/lib
LIBS     = -lrose

BUILDDIR = build
SOURCES  = $(wildcard tools/*.cpp)
TOOLS    = $(patsubst tools/%.cpp,$(BUILDDIR)/%,$(SOURCES))

.PHONY: all clean check

all: $(TOOLS)

$(BUILDDIR)/%: tools/%.cpp
	@mkdir -p $(BUILDDIR)
	$(CXX) $(CXXFLAGS) $< -o $@ $(LDFLAGS) $(LIBS)

check: all
	@for tool in $(TOOLS); do \
		echo "Testing $$tool..."; \
		LD_LIBRARY_PATH=$(ROSE_INSTALL)/lib $$tool -c tests/hello.c; \
	done

clean:
	rm -rf $(BUILDDIR)

Example: Identity Translator

Minimal ROSE tool that parses and unparses code:

// tools/identity.cpp
#include "rose.h"

int main(int argc, char* argv[]) {
    SgProject* project = frontend(argc, argv);
    if (!project) return 1;
    
    AstTests::runAllTests(project);
    return backend(project);
}

Build and run:

make
./build/identity -c tests/hello.c
# Output: rose_hello.c (unparsed)

Example: Call Graph Generator

// tools/callgraph.cpp
#include "rose.h"
#include <CallGraph.h>

int main(int argc, char* argv[]) {
    ROSE_INITIALIZE;
    SgProject* project = new SgProject(argc, argv);
    
    CallGraphBuilder builder(project);
    builder.buildCallGraph();
    
    AstDOTGeneration dotgen;
    dotgen.writeIncidenceGraphToDOTFile(
        builder.getGraph(), "callgraph.dot");
    
    return 0;
}

Example: AST Node Counter

// tools/ast_stats.cpp
#include "rose.h"
#include <map>

class NodeCounter : public AstSimpleProcessing {
public:
    std::map<std::string, int> counts;
    
    void visit(SgNode* node) override {
        if (node) counts[node->class_name()]++;
    }
};

int main(int argc, char* argv[]) {
    SgProject* project = frontend(argc, argv);
    
    NodeCounter counter;
    counter.traverseInputFiles(project, preorder);
    
    for (auto& [name, count] : counter.counts)
        std::cout << name << ": " << count << "\n";
    
    return 0;
}

Common ROSE Headers

Header Purpose
rose.h Main header (includes most things)
CallGraph.h Call graph construction
AstDOTGeneration.h DOT output for AST/graphs
sageInterface.h AST manipulation utilities

AST Traversal Patterns

Simple Traversal (preorder/postorder)

class MyTraversal : public AstSimpleProcessing {
    void visit(SgNode* node) override {
        // Process each node
    }
};

MyTraversal t;
t.traverseInputFiles(project, preorder);

Top-Down with Inherited Attributes

class MyTraversal : public AstTopDownProcessing<int> {
    int evaluateInheritedAttribute(SgNode* node, int depth) override {
        return depth + 1;  // Pass to children
    }
};

Bottom-Up with Synthesized Attributes

class MyTraversal : public AstBottomUpProcessing<int> {
    int evaluateSynthesizedAttribute(SgNode* node, 
        SynthesizedAttributesList childAttrs) override {
        int sum = 0;
        for (auto& attr : childAttrs) sum += attr;
        return sum + 1;  // Return to parent
    }
};

Testing in Container

# Run from host
docker exec -w /work rose-tools-dev make check

# Or interactively
docker exec -it rose-tools-dev bash
cd /work
make && make check

Troubleshooting

"rose.h not found"

# Check include path
echo $ROSE/include/rose
ls $ROSE/include/rose/rose.h

"cannot find -lrose"

# Check library path
ls $ROSE/lib/librose.so

Runtime: "librose.so not found"

# Set library path
export LD_LIBRARY_PATH=$ROSE/lib:$LD_LIBRARY_PATH

Segfault on large files

# Increase stack size
ulimit -s unlimited

Container Reference

Path Contents
/rose/install ROSE installation (headers, libs, bins)
/rose/install/include/rose Header files
/rose/install/lib librose.so and dependencies
/rose/install/bin ROSE tools (identityTranslator, etc.)
/work Mounted workspace (your code)