Browse Source

Got compile-time code execution working

* I made the mistake of not having exactly the same compilation settings
for the executable vs. the DLL.
* I wasn't specifying a dynamic runtime either, which is essential for
the DLL to share the same memory.
* My macro was missing escape characters. I need to fix that eventually
* Fix CRC -> CRT typo in readme
* Build everything in debug (cleanup coming)
windows-support
Macoy Madson 6 months ago
parent
commit
61182f9ebe
8 changed files with 109 additions and 15 deletions
  1. +2
    -1
      .gitignore
  2. +6
    -6
      Bootstrap_MSVC.cake
  3. +84
    -0
      Build_SimpleMacros.bat
  4. +1
    -1
      ReadMe.org
  5. +5
    -1
      src/Logging.hpp
  6. +9
    -4
      src/ModuleManager.cpp
  7. +1
    -1
      src/Tokenizer.hpp
  8. +1
    -1
      test/SimpleMacros.cake

+ 2
- 1
.gitignore View File

@ -50,4 +50,5 @@ cakelisp_cache/
VisualStudio/Cakelisp/Debug
VisualStudio/Cakelisp/.vs
output.exe
output.exe
*.pdb

+ 6
- 6
Bootstrap_MSVC.cake View File

@ -20,25 +20,25 @@
"Build.cpp"
"Main.cpp")
(add-build-options "/DWINDOWS" "/DCAKELISP_EXPORTING" "/EHsc"
;;; DEBUG ONLY!
"/Zi" "/FS" "/Fd:bin\cakelisp.pdb" "/DEBUG:FASTLINK")
(add-build-options "/nologo" "/DWINDOWS" "/DCAKELISP_EXPORTING" "/EHsc"
;;; DEBUG ONLY! Note that link also needs /DEBUG
"/Zi" "/FS" "/Fd:bin\cakelisp.pdb" "/DEBUG:FASTLINK" "/MDd")
(set-cakelisp-option build-time-compiler "cl.exe")
(set-cakelisp-option build-time-compile-arguments
"/nologo" "/c" 'source-input 'object-output
"/c" 'source-input 'object-output
'include-search-dirs 'additional-options)
(set-cakelisp-option compile-time-compiler "cl.exe")
(set-cakelisp-option compile-time-compile-arguments
"/nologo" "/c" 'source-input 'object-output
"/nologo" "/DEBUG:FASTLINK" "/MDd" "/c" 'source-input 'object-output
'cakelisp-headers-include)
;; "-fPIC"
;; cl.exe for linker also works
(set-cakelisp-option build-time-linker "link.exe")
(set-cakelisp-option build-time-link-arguments
"/nologo" 'executable-output 'object-input)
"/nologo" "/DEBUG:FASTLINK" 'executable-output 'object-input)
;; Use separate build configuration in case other things build files from src/
(add-build-config-label "Bootstrap_Windows")

+ 84
- 0
Build_SimpleMacros.bat View File

@ -0,0 +1,84 @@
echo off
rem Set environment variables. The user may need to adjust this path
rem See https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-160#developer_command_file_locations
if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" (
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
) else (
echo This script builds using MSVC.
echo You must download and install MSVC before it will work. Download it here:
echo https://visualstudio.microsoft.com/downloads/
echo Select workloads for C++ projects. Ensure you install the C++ developer tools.
echo If you're still seeing this, you may need to edit Build.bat to your vcvars path
echo Please see the following link:
echo https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-160
goto fail
)
if not exist "bin" (
mkdir bin
)
if not exist "bin\cakelisp_bootstrap.exe" (
goto manualBuild
) else (
goto bootstrapBuild
)
:manualBuild
CL.exe src/Tokenizer.cpp ^
src/Evaluator.cpp ^
src/Utilities.cpp ^
src/FileUtilities.cpp ^
src/Converters.cpp ^
src/Writer.cpp ^
src/Generators.cpp ^
src/GeneratorHelpers.cpp ^
src/RunProcess.cpp ^
src/OutputPreambles.cpp ^
src/DynamicLoader.cpp ^
src/ModuleManager.cpp ^
src/Logging.cpp ^
src/Build.cpp ^
src/Main.cpp ^
/EHsc /MP /DWINDOWS /DCAKELISP_EXPORTING ^
/Fe"bin\cakelisp_bootstrap" /Zi /Fd"bin\cakelisp_bootstrap.pdb" /DEBUG:FASTLINK
echo %ERRORLEVEL%
@if %ERRORLEVEL% == 0 (
echo Success building
rem Clean up working directory
del *.obj
goto bootstrapBuild
) else (
echo Error while building
goto fail
)
:bootstrapBuild
"bin\cakelisp_bootstrap.exe" Bootstrap_MSVC.cake
@if %ERRORLEVEL% == 0 (
echo Success! Use bin\cakelisp.exe to build your programs
goto build_user
) else (
echo Error while bootstrapping cakelisp
goto fail
)
:build_user
"bin\cakelisp.exe" --verbose-processes --execute test/SimpleMacros.cake
@if %ERRORLEVEL% == 0 (
echo Success!
goto success
) else (
echo Error while building user program
goto fail
)
:fail
goto end
:success
goto end
:end
pause

+ 1
- 1
ReadMe.org View File

@ -136,7 +136,7 @@ You can refer to an existing project in ~cakelisp/VisualStudio~. The steps to cr
#+BEGIN_SRC sh
CAKELISP_EXPORTING;_CRT_SECURE_NO_WARNINGS;WINDOWS;
#+END_SRC
~CAKELISP_EXPORTING~ indicates Cakelisp should export its symbols to DLLs. The ~CRC~ definition is going to be removed eventually; it makes MSVC more lenient with some errors Cakelisp has. The ~WINDOWS~ definition ensures you build with Cakelisp's Windows-specific code enabled
~CAKELISP_EXPORTING~ indicates Cakelisp should export its symbols to DLLs. The ~CRT~ definition is going to be removed eventually; it makes MSVC more lenient with some errors Cakelisp has. The ~WINDOWS~ definition ensures you build with Cakelisp's Windows-specific code enabled
- Hit ~F5~ or go to ~Debug -> Start Debugging~. Visual Studio will build Cakelisp, and if it succeeds, launch Cakelisp. If you have no ~Command Arguments~ set, you should see the Cakelisp help output in a command window.
This project is for building Cakelisp itself; you don't need to make any new projects for your projects written in Cakelisp (in ~.cake~ files). Change the ~Debugging -> Command Arguments~ setting to build different Cakelisp files, or change the ~Working Directory~ to build a different Cakelisp project (e.g. one in a separate repository).


+ 5
- 1
src/Logging.hpp View File

@ -1,3 +1,7 @@
#pragma once
#include "Exporting.hpp"
struct LoggingSettings
{
// verbosity
@ -25,4 +29,4 @@ struct LoggingSettings
bool strictIncludes;
};
extern LoggingSettings logging;
extern CAKELISP_API LoggingSettings logging;

+ 9
- 4
src/ModuleManager.cpp View File

@ -82,8 +82,12 @@ void moduleManagerInitialize(ModuleManager& manager)
// Need this to properly add declspec for importing symbols
{ProcessCommandArgumentType_String, "/DWINDOWS"},
// TODO Fix
{ProcessCommandArgumentType_String, "/DEBUG"},
{ProcessCommandArgumentType_String, "/DEBUG:FASTLINK"},
{ProcessCommandArgumentType_String, "/Zi"},
// Need to use dynamic runtime so everything is shared. Cakelisp must be built with this as well
// (use just /MD for release)
// SEe https://stackoverflow.com/questions/22279052/c-passing-stdstring-by-reference-to-function-in-dll
{ProcessCommandArgumentType_String, "/MDd"},
{ProcessCommandArgumentType_String, "/Fp\"cakelisp_cache\\comptime_my_print.pdb\""},
{ProcessCommandArgumentType_String, "/c"},
{ProcessCommandArgumentType_SourceInput, EmptyString},
@ -94,11 +98,12 @@ void moduleManagerInitialize(ModuleManager& manager)
manager.environment.compileTimeLinkCommand.fileToExecute = "link.exe";
manager.environment.compileTimeLinkCommand.arguments = {
{ProcessCommandArgumentType_String, "/nologo"},
{ProcessCommandArgumentType_String, "/DLL"},
{ProcessCommandArgumentType_String, "/nologo"},
{ProcessCommandArgumentType_String, "/DLL"},
{ProcessCommandArgumentType_DynamicLibraryOutput, EmptyString},
{ProcessCommandArgumentType_ObjectInput, EmptyString},
// On Windows, .exes create .lib files for exports
{ProcessCommandArgumentType_String, "/DEBUG:FASTLINK"},
// On Windows, .exes create .lib files for exports
{ProcessCommandArgumentType_String, "/LIBPATH:\"bin\""},
{ProcessCommandArgumentType_String, "cakelisp.lib"}};


+ 1
- 1
src/Tokenizer.hpp View File

@ -47,4 +47,4 @@ bool writeStringToBufferErrorToken(const char* str, char** at, char* bufferStart
const Token& token);
bool appendTokenToString(const Token& token, char** at, char* bufferStart, int bufferSize);
extern int g_totalLinesTokenized;
extern CAKELISP_API int g_totalLinesTokenized;

+ 1
- 1
test/SimpleMacros.cake View File

@ -2,7 +2,7 @@
(defmacro my-print (message string)
(printf "Compile-time print!\n")
(tokenize-push output (printf "%s\n" (token-splice message)))
(tokenize-push output (printf \"%s\\n\" (token-splice message)))
(return true))
(defun main(&return int)


Loading…
Cancel
Save