From a96d8df57b368070e06c2f7b236c0b968a93f6e6 Mon Sep 17 00:00:00 2001 From: Ed Beroset Date: Sun, 8 Nov 2020 10:09:26 -0500 Subject: [PATCH] Add support for 64-bit NASM assembly. --- config/CMakeLists.txt | 1 + config/asm/rules.txt | 20 ++++++++++++++++++++ config/asm/srclevel.cmake.txt | 4 ++++ config/asm/toplevel.cmake.txt | 13 +++++++++++++ config/autoproject.conf.in | 10 ++++++++++ src/AutoProject.cpp | 18 ++++++++++++++---- src/main.cpp | 4 ++++ 7 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 config/asm/rules.txt create mode 100644 config/asm/srclevel.cmake.txt create mode 100644 config/asm/toplevel.cmake.txt diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt index 7b0631e..8e92283 100644 --- a/config/CMakeLists.txt +++ b/config/CMakeLists.txt @@ -14,4 +14,5 @@ endif() INSTALL(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/c DESTINATION share/autoproject/config) INSTALL(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/cpp DESTINATION share/autoproject/config) +INSTALL(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/asm DESTINATION share/autoproject/config) INSTALL(FILES "${PROJECT_BINARY_DIR}/autoproject.conf" DESTINATION share/autoproject/config) diff --git a/config/asm/rules.txt b/config/asm/rules.txt new file mode 100644 index 0000000..729e77c --- /dev/null +++ b/config/asm/rules.txt @@ -0,0 +1,20 @@ +# rules.txt +# +# AutoProject rules file. +# +# Each line is composed of three fields each separated with the '@' character +# The fields are "Rule regex", "CMake extras" and "Libraries" +# +# The "Rule regex" is the regular expression that triggers the rule and is +# determined by searching each line of the input sources for the regex +# +# The "CMake extras" field is the only one that can be empty and represents extra +# rules that may need to be inserted before the "add_executable" line. If +# multiple lines are needed, separate them using "\n" within the field. +# +# The "Libraries" is the list of additional libraries that need to be added +# to the "target_link_libraries" line. If the same library is needed by +# multiple components, only a single instance will appear. The ordering +# of libraries is arbitrary. +# +#\s*#include\s*<(experimental/)?filesystem>@@stdc++fs diff --git a/config/asm/srclevel.cmake.txt b/config/asm/srclevel.cmake.txt new file mode 100644 index 0000000..69117df --- /dev/null +++ b/config/asm/srclevel.cmake.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.1) +{extras} +add_executable({projname} {srcnames}) +target_link_libraries({projname} {libraries}) diff --git a/config/asm/toplevel.cmake.txt b/config/asm/toplevel.cmake.txt new file mode 100644 index 0000000..5db6d79 --- /dev/null +++ b/config/asm/toplevel.cmake.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.1) +project({projname}) +enable_language(ASM_NASM) +set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64) +set(CMAKE_ASM_NASM_COMPILE_OBJECT " \ + -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o -l .lst") +set(CMAKE_ASM_NASM_LINK_EXECUTABLE "ld -o ") +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_ASM_NASM_FLAGS "${ASM_NASM_FLAGS} -g -Fdwarf") +else() + set(CMAKE_ASM_NASM_FLAGS "${ASM_NASM_FLAGS}") +endif() +add_subdirectory(src) diff --git a/config/autoproject.conf.in b/config/autoproject.conf.in index 47a3bd0..b8fae1d 100644 --- a/config/autoproject.conf.in +++ b/config/autoproject.conf.in @@ -26,3 +26,13 @@ RulesFileName=rules.txt TopLevelCMakeFileName=toplevel.cmake.txt # The name of the source level CMake file SrcLevelCMakeFileName=srclevel.cmake.txt + +[asm] +# The name of the subdirectory under ConfigFileDir +Subdir=asm +# The name of the rules file +RulesFileName=rules.txt +# The name of the top level CMake file +TopLevelCMakeFileName=toplevel.cmake.txt +# The name of the source level CMake file +SrcLevelCMakeFileName=srclevel.cmake.txt diff --git a/src/AutoProject.cpp b/src/AutoProject.cpp index c7d404f..e97af99 100644 --- a/src/AutoProject.cpp +++ b/src/AutoProject.cpp @@ -117,9 +117,11 @@ bool AutoProject::createProject(bool overwrite) { } else { if (thislang == "c") { srcfilename = fs::path(srcdir) / "main.c"; - } else { + } else if (thislang == "c++") { srcfilename = fs::path(srcdir) / "main.cpp"; - } + } else if (thislang == "asm") { + srcfilename = fs::path(srcdir) / "main.asm"; + } } if (firstFile) { makeTree(overwrite); @@ -150,8 +152,10 @@ bool AutoProject::createProject(bool overwrite) { firstFile = false; if (thislang == "c") { srcfilename = fs::path(srcdir) / "main.c"; - } else { + } else if (thislang == "c++") { srcfilename = fs::path(srcdir) / "main.cpp"; + } else if (thislang == "asm") { + srcfilename = fs::path(srcdir) / "main.asm"; } srcfile.open(srcfilename); if (srcfile) { @@ -257,6 +261,7 @@ void AutoProject::checkRules(const std::string &line) { void AutoProject::checkLanguageTags(const std::string& line) { static const std::regex tagcpp{"### tags: \\[.*'c\\+\\+'.*\\]"}; static const std::regex tagc{"### tags: \\[.*'c'.*\\]"}; + static const std::regex tagasm{"### tags: \\[.*'assembly'.*\\]"}; std::smatch pieces; if (std::regex_match(line, pieces, tagcpp)) { thislang = "c++"; @@ -268,6 +273,11 @@ void AutoProject::checkLanguageTags(const std::string& line) { rules = loadrules(lang[thislang].rulesfilename); toplevelfilename = lang[thislang].toplevelcmakefilename; srclevelfilename = lang[thislang].srclevelcmakefilename; + } else if (std::regex_match(line, pieces, tagasm)) { + thislang = "asm"; + rules = loadrules(lang[thislang].rulesfilename); + toplevelfilename = lang[thislang].toplevelcmakefilename; + srclevelfilename = lang[thislang].srclevelcmakefilename; } } @@ -281,7 +291,7 @@ std::ostream& operator<<(std::ostream& out, const AutoProject &ap) { /// returns true if passed file extension is an identified source code extension. bool isSourceExtension(const std::string_view ext) { - static const std::unordered_set source_extensions{".cpp", ".c", ".h", ".hpp"}; + static const std::unordered_set source_extensions{".cpp", ".c", ".h", ".hpp", ".asm"}; return source_extensions.find(ext) != source_extensions.end(); } diff --git a/src/main.cpp b/src/main.cpp index 70760e6..9177f01 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -132,6 +132,10 @@ int main(int argc, char *argv[]) { configuration.lang["c"].toplevelcmakefilename = configuration.configfiledir + "/" + cfg.get_value("c", "Subdir") + "/" + cfg.get_value("c", "TopLevelCMakeFileName"); configuration.lang["c"].srclevelcmakefilename = configuration.configfiledir + "/" + cfg.get_value("c", "Subdir") + "/" + cfg.get_value("c", "SrcLevelCMakeFileName"); + configuration.lang["asm"].rulesfilename = configuration.configfiledir + "/" + cfg.get_value("asm", "Subdir") + "/" + cfg.get_value("asm", "RulesFileName"); + configuration.lang["asm"].toplevelcmakefilename = configuration.configfiledir + "/" + cfg.get_value("asm", "Subdir") + "/" + cfg.get_value("asm", "TopLevelCMakeFileName"); + configuration.lang["asm"].srclevelcmakefilename = configuration.configfiledir + "/" + cfg.get_value("asm", "Subdir") + "/" + cfg.get_value("asm", "SrcLevelCMakeFileName"); + if (argc - processed_args != 2) { std::cerr << "Usage: autoproject project.md\nCreates a CMake build tree under 'project' subdirectory\n"; for (int i=processed_args+1; i < argc; ++i) {