Verified Commit 34049d4d authored by nagayama15's avatar nagayama15

build: import cxxopts

parent fc366fb6
cmake_minimum_required(VERSION 3.0.0)
set(CMAKE_CXX_FLAGS "-std=c++2a -Wall -Wextra -Werror -pedantic")
set(CMAKE_CXX_FLAGS "-std=c++17 -Wall -Wextra -Werror -pedantic")
set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g3 -Og")
......@@ -22,8 +22,10 @@ find_package(Threads)
include(ExternalProject)
include(cmake/boost.cmake)
include(cmake/binaryen.cmake)
include(cmake/cxxopts.cmake)
include(cmake/fmt.cmake)
include(cmake/googletest.cmake)
add_subdirectory(lib)
add_subdirectory(src)
add_subdirectory(test)
ExternalProject_Add(cxxopts
GIT_REPOSITORY "https://github.com/jarro2783/cxxopts.git"
GIT_TAG "master"
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/cxxopts"
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/cxxopts/src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/cxxopts/build"
STAMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/cxxopts/stamp"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
UPDATE_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
ExternalProject_Get_Property(cxxopts source_dir)
ExternalProject_Get_Property(cxxopts binary_dir)
add_library(cxxopts::cxxopts INTERFACE IMPORTED)
make_directory("${source_dir}/include") # To suppress non-exist directory warnings
target_include_directories(cxxopts::cxxopts INTERFACE
"${source_dir}/include"
)
add_dependencies(cxxopts::cxxopts cxxopts)
add_library(kyut INTERFACE
)
target_include_directories(kyut INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}"
)
target_link_libraries(kyut INTERFACE
Threads::Threads
binaryen::binaryen
fmtlib::fmt
)
#ifndef INCLUDE_kyut_EmbeddingMethod_hpp
#define INCLUDE_kyut_EmbeddingMethod_hpp
#include <string_view>
#include <unordered_map>
#include <boost/optional.hpp>
namespace kyut {
enum class EmbeddingMethod {
FunctionOrdering,
OperandSwapping,
};
constexpr std::string_view to_string(EmbeddingMethod m) noexcept {
switch (m) {
case EmbeddingMethod::FunctionOrdering:
return "function-ordering";
case EmbeddingMethod::OperandSwapping:
return "operand-swapping";
default:
return "unknown";
}
}
inline boost::optional<EmbeddingMethod> embedding_method_from(std::string_view s) noexcept {
static const std::unordered_map<std::string_view, EmbeddingMethod> embedding_methods = {
{to_string(EmbeddingMethod::FunctionOrdering), EmbeddingMethod::FunctionOrdering},
{to_string(EmbeddingMethod::OperandSwapping), EmbeddingMethod::OperandSwapping},
};
if (const auto it = embedding_methods.find(s); it != std::end(embedding_methods)) {
return it->second;
}
return boost::none;
}
inline std::ostream& operator<<(std::ostream& ostream, EmbeddingMethod m) {
return ostream << to_string(m);
}
} // namespace kyut
#endif // INCLUDE_kyut_EmbeddingMethod_hpp
add_executable(snpi snpi.cpp)
add_executable(snpi
snpi.cpp
)
target_link_libraries(snpi
kyut
cxxopts::cxxopts
)
#include <iostream>
#include <string>
#include <fmt/printf.h>
#include "cxxopts.hpp"
#include "kyut/EmbeddingMethod.hpp"
int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) {
std::cout << "snpi" << std::endl;
namespace {
const std::string command = "snpi";
const std::string version = "0.1.0";
const std::string description = "WebAssembly watermark embedder";
struct Options {
std::string input;
std::string output;
kyut::EmbeddingMethod method;
};
Options parse_options(int argc, char** argv) {
cxxopts::Options options{command, fmt::format("{} - {}", command, description)};
// clang-format off
options
.add_options()
("v,version", "Show version")
("h,help", "Print help")
("o,output", "Output file (required)", cxxopts::value<std::string>(), "OUTPUT")
("m,method", "Embedding method (required)", cxxopts::value<std::string>(), "function-ordering, operand-swapping")
("input", "Input file", cxxopts::value<std::string>())
;
// clang-format on
options
.positional_help("INPUT")
.parse_positional("input");
try {
const auto result = options.parse(argc, const_cast<const char**&>(argv));
if (result.count("version") > 0) {
// Show version.
fmt::print("{} v{}\n", command, version);
std::exit(EXIT_SUCCESS);
}
if (result.count("help") > 0) {
// Print help.
fmt::print("{}\n", options.help());
std::exit(EXIT_SUCCESS);
}
if (result.count("input") == 0) {
throw std::runtime_error{"no input file"};
}
if (result.count("output") == 0) {
throw std::runtime_error{"no output file"};
}
if (result.count("method") == 0) {
throw std::runtime_error{"no embedding method"};
}
const auto input = result["input"].as<std::string>();
const auto output = result["output"].as<std::string>();
const auto method_text = result["method"].as<std::string>();
const auto method = kyut::embedding_method_from(method_text)
.value_or_eval([method_text]() -> kyut::EmbeddingMethod {
throw std::runtime_error{fmt::format("unknown embedding method: {}", method_text)};
});
return Options{
input,
output,
method,
};
} catch (const std::exception& e) {
fmt::print(std::cerr, "{}\n", e.what());
std::exit(EXIT_FAILURE);
}
}
} // namespace
int main(int argc, char* argv[]) {
const auto opts = parse_options(argc, argv);
}
......@@ -5,8 +5,7 @@ add_executable(test_kyut
)
target_link_libraries(test_kyut
Threads::Threads
fmtlib::fmt
kyut
googletest::gtest
googletest::gtest_main
)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment