cmake_minimum_required(VERSION 3.28) # grab commands include(ExternalProject) # set our stuff for cross compiling set(CMAKE_CXX_STANDARD 23) set_property(DIRECTORY . PROPERTY INCLUDE_DIRECTORIES "") # -- generate a file or two -- configure_file(lindows.ld.in lindows.ld @ONLY) # -- macros for managing this nightmare multi toolchain shitshow -- # dependencies add_executable(LindowsCompilerSpec IMPORTED) set_property(TARGET LindowsCompilerSpec PROPERTY IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lindows.spec") #add_executable(LindowsLinkerScript IMPORTED) #set_property(TARGET LindowsLinkerScript PROPERTY IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/lindows.ld") add_executable(LindowsLinkerScript IMPORTED) set_property(TARGET LindowsLinkerScript PROPERTY IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lindows.ld.in") #add_dependencies(LindowsLinkerScript LindowsLinkerScriptSource) # compiler stuff set(LW_CROSS_CC "${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/bin/gcc") set(LW_CROSS_CXX "${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/bin/g++") set(LW_CROSS_LD "${LW_CROSS_CC}") set(LW_CROSS_INCFLAGS -isystem${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/include/c++/13.2.0 -isystem${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/lib/gcc/x86_64-pc-linux-gnu/13.2.0/include -isystem${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/lib/gcc/x86_64-pc-linux-gnu/13.2.0/include-fixed -isystem${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/include/c++/13.2.0/x86_64-pc-linux-gnu -isystem${CMAKE_CURRENT_BINARY_DIR}/glibc/prefix/include -isystem${CMAKE_CURRENT_BINARY_DIR}/linux/headers/include) set(LW_CROSS_CFLAGS -nostdinc ${LW_CROSS_INCFLAGS}) set(LW_CROSS_CXXFLAGS -nostdinc ${LW_CROSS_INCFLAGS}) set(LW_CROSS_LIBFLAGS -L${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/lib -L${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/lib64 -L${CMAKE_CURRENT_BINARY_DIR}/glibc/lib) set(LW_CROSS_LDFLAGS ${LW_CROSS_LIBFLAGS} -Xlinker --dynamic-linker /Windows/System32/ld-linux-x86-64.so.2 -Wl,-T,${CMAKE_CURRENT_BINARY_DIR}/lindows.ld --specs=${CMAKE_CURRENT_SOURCE_DIR}/lindows.spec) string(REPLACE ";" " " LW_CROSS_CFLAGS_FLAT "${LW_CROSS_CFLAGS}") string(REPLACE ";" " " LW_CROSS_CXXFLAGS_FLAT "${LW_CROSS_CXXFLAGS}") string(REPLACE ";" " " LW_CROSS_LDFLAGS_FLAT "${LW_CROSS_LDFLAGS}") # defines a project function(lw_project PROJECTNAME) set(cpa_flag) set(cpa_single DESCRIPTION TARGET) set(cpa_multi) cmake_parse_arguments(PARSE_ARGV 1 ARG "${cpa_flag}" "${cpa_single}" "${cpa_multi}") if(NOT ARG_DESCRIPTION) set(ARG_DESCRIPTION "No description provided.") endif() if(NOT ARG_TARGET) set(ARG_TARGET "HOST") endif() project(PROJECTNAME DESCRIPTION "${ARG_DESCRIPTION}" ) set(LW_TARGET "${ARG_TARGET}" PARENT_SCOPE) if(${ARG_TARGET} STREQUAL "HOST") elseif(${ARG_TARGET} STREQUAL "LINDOWS") set(CMAKE_C_COMPILER "${LW_CROSS_CC}" PARENT_SCOPE) set(CMAKE_CXX_COMPILER "${LW_CROSS_CXX}" PARENT_SCOPE) set_property(DIRECTORY . PROPERTY INCLUDE_DIRECTORIES "") else() message(FATAL_ERROR "Unrecognized target type \"${ARG_TARGET}\"") endif() endfunction() # defines a executable target, this must be used if lw_project is used function(lw_add_executable NAME) set(cpa_flag) set(cpa_single) set(cpa_multi SOURCES) cmake_parse_arguments(PARSE_ARGV 1 ARG "${cpa_flag}" "${cpa_single}" "${cpa_multi}") add_executable(${NAME}) if(ARG_SOURCES) target_sources(${NAME} PRIVATE ${ARG_SOURCES}) target_compile_options(${NAME} PRIVATE $<$:${LW_CROSS_CFLAGS}> $<$:${LW_CROSS_CXXFLAGS}> ) target_link_options(${NAME} PRIVATE ${LW_CROSS_LDFLAGS}) endif() if(LW_TARGET) set_property(TARGET ${NAME} APPEND PROPERTY LINK_DEPENDS $ $ ) set_property(SOURCE TARGET_DIRECTORY ${NAME} APPEND PROPERTY OBJECT_DEPENDS GCC-install ) target_include_directories(${NAME} PUBLIC "${CMAKE_SOURCE_DIR}/common/include") else() message(FATAL_ERROR "LW_TARGET not defined, are you in a lw_project?") endif() endfunction() # defines a library target. this must be used if lw_project is used function(lw_add_library NAME) set(cpa_flag SHARED) set(cpa_single) set(cpa_multi SOURCES) cmake_parse_arguments(PARSE_ARGV 1 ARG "${cpa_flag}" "${cpa_single}" "${cpa_multi}") if (ARG_SHARED) add_library(${NAME} SHARED) else() add_library(${NAME}) endif() if(ARG_SOURCES) target_sources(${NAME} PRIVATE ${ARG_SOURCES}) target_compile_options(${NAME} PRIVATE $<$:${LW_CROSS_CFLAGS}> $<$:${LW_CROSS_CXXFLAGS}> ) target_link_options(${NAME} PRIVATE ${LW_CROSS_LDFLAGS}) endif() if(LW_TARGET) set_property(TARGET ${NAME} APPEND PROPERTY LINK_DEPENDS $ $ ) set_property(SOURCE TARGET_DIRECTORY ${NAME} APPEND PROPERTY OBJECT_DEPENDS GCC-install ) target_include_directories(${NAME} PUBLIC "${CMAKE_SOURCE_DIR}/common/include") else() message(FATAL_ERROR "LW_TARGET not defined, are you in a lw_project?") endif() endfunction() # -- lindows -- # dear god project(lindows) # find our programs set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake.d/") find_package(NTFS3g REQUIRED) find_package(CoreUtils REQUIRED) find_package(MTools REQUIRED) find_package(Python REQUIRED) # for GRUB # TODO: find_package for bison (for GRUB) # TODO: find_package for flex (for GRUB) # TODO: find_package for sfdisk (for disk image generation) # make c drive mount point file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lindows_c") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lindows_efi") # build cross compiler file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/gcc") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix") ExternalProject_Add(GCC GIT_REPOSITORY "git://gcc.gnu.org/git/gcc.git" GIT_TAG "releases/gcc-13.2.0" GIT_PROGRESS TRUE UPDATE_COMMAND "" CONFIGURE_COMMAND /configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix --target=x86_64-pc-linux-gnu --enable-languages=c,c++ --disable-nls --disable-bootstrap BUILD_COMMAND make INSTALL_COMMAND make install COMMAND cp -r ${CMAKE_BINARY_DIR}/gcc/prefix/lib64 ${CMAKE_BINARY_DIR}/gcc/lib64 STEP_TARGETS install ) # build grub file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/grub") ExternalProject_Add(GRUB GIT_REPOSITORY "https://git.savannah.gnu.org/git/grub.git" GIT_TAG "grub-2.12" GIT_SHALLOW TRUE GIT_PROGRESS TRUE UPDATE_COMMAND "" # the commit is fixed, we will never need to update # this should make it stop rebuilding every `make` CONFIGURE_COMMAND ./bootstrap COMMAND ./configure --host=x86_64-pc-linux-gnu --target=x86_64 --with-platform=efi --disable-efiemu --prefix=${CMAKE_CURRENT_BINARY_DIR}/grub BUILD_COMMAND make BUILD_IN_SOURCE TRUE INSTALL_COMMAND make install ) # build linux add_executable(LinuxConfig IMPORTED) set_property(TARGET LinuxConfig PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/src/linux/config) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/linux") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/linux/modules") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/linux/headers") ExternalProject_Add(Linux GIT_REPOSITORY "https://github.com/torvalds/linux" GIT_TAG "v6.7" GIT_PROGRESS TRUE UPDATE_COMMAND "" CONFIGURE_COMMAND ${CoreUtils_Copy_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/src/linux/config .config BUILD_COMMAND make BUILD_IN_SOURCE TRUE INSTALL_COMMAND ${CoreUtils_Copy_EXECUTABLE} arch/x86_64/boot/bzImage ${CMAKE_CURRENT_BINARY_DIR}/linux COMMAND make modules_install INSTALL_MOD_PATH=${CMAKE_CURRENT_BINARY_DIR}/linux/modules COMMAND make headers_install INSTALL_HDR_PATH=${CMAKE_CURRENT_BINARY_DIR}/linux/headers "" STEP_TARGETS install ) ExternalProject_Add_StepDependencies(Linux configure LinuxConfig) add_executable(LinuxKernel IMPORTED) set_property(TARGET LinuxKernel PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/linux/bzImage) # build glibc file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/glibc") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/glibc/prefix") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/glibc/lib") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/glibc/bin") ExternalProject_Add(GLibC GIT_REPOSITORY "https://sourceware.org/git/glibc.git" GIT_TAG "glibc-2.39" GIT_PROGRESS TRUE UPDATE_COMMAND "" PATCH_COMMAND git apply ${CMAKE_CURRENT_SOURCE_DIR}/src/glibc/patches/lindows.patch CONFIGURE_COMMAND /configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/glibc/prefix --with-headers=${CMAKE_CURRENT_BINARY_DIR}/linux/headers/include --enable-kernel=6.7.0 --host=x86_64-pc-linux-gnu --enable-shared BUILD_COMMAND make INSTALL_COMMAND make install COMMAND sh -c "cp -r ${CMAKE_CURRENT_BINARY_DIR}/glibc/prefix/sbin/* ${CMAKE_CURRENT_BINARY_DIR}/glibc/bin" COMMAND sh -c "cp -r ${CMAKE_CURRENT_BINARY_DIR}/glibc/prefix/bin/* ${CMAKE_CURRENT_BINARY_DIR}/glibc/bin" COMMAND sh -c "cp -r ${CMAKE_CURRENT_BINARY_DIR}/glibc/prefix/libexec/* ${CMAKE_CURRENT_BINARY_DIR}/glibc/lib" COMMAND sh -c "cp -r ${CMAKE_CURRENT_BINARY_DIR}/glibc/prefix/lib/* ${CMAKE_CURRENT_BINARY_DIR}/glibc/lib" STEP_TARGETS install ) add_executable(GLibCPatch IMPORTED) set_property(TARGET GLibCPatch PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/src/glibc/patches/lindows.patch) ExternalProject_Add_StepDependencies(GLibC patch GLibCPatch) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ncurses") ExternalProject_Add(NCurses # oh wow no git URL "https://invisible-island.net/archives/ncurses/ncurses-6.4.tar.gz" URL_MD5 "5a62487b5d4ac6b132fe2bf9f8fad29b" # generated with md5sum at 2024-02-29 12:00 UPDATE_COMMAND "" CONFIGURE_COMMAND env "CC=${LW_CROSS_CC}" "CXX=${LW_CROSS_CXX}" "LD=${LW_CROSS_LD}" "CFLAGS=${LW_CROSS_CFLAGS_FLAT}" "CXXFLAGS=${LW_CROSS_CXXFLAGS_FLAT}" "LDFLAGS=${LW_CROSS_LDFLAGS_FLAT}" /./configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/ncurses --host=x86_64-pc-linux-gnu --without-ada --without-manpages --enable-mixed-case --without-gpm --with-shared BUILD_COMMAND make INSTALL_COMMAND make install STEP_TARGETS install ) ExternalProject_Add_StepDependencies(NCurses configure GCC) ExternalProject_Add_StepDependencies(NCurses build LindowsCompilerSpec LindowsLinkerScript) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bash") ExternalProject_Add(Bash GIT_REPOSITORY "https://git.savannah.gnu.org/git/bash.git" GIT_TAG "bash-5.2" GIT_PROGRESS TRUE UPDATE_COMMAND "" CONFIGURE_COMMAND env "CC=${LW_CROSS_CC}" "LD=${LW_CROSS_LD}" "CFLAGS=${LW_CROSS_CFLAGS_FLAT}" "LDFLAGS=${LW_CROSS_LDFLAGS_FLAT}" /configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/bash --host=x86_64-pc-linux-gnu --with-curses BUILD_COMMAND make INSTALL_COMMAND make install STEP_TARGETS install ) ExternalProject_Add_StepDependencies(Bash configure GCC NCurses) ExternalProject_Add_StepDependencies(Bash build LindowsCompilerSpec LindowsLinkerScript) # this should probably be a shell script, i unfortunately do not care add_custom_command(OUTPUT lindows_c.img # create empty 128MiB disk image COMMAND "${CoreUtils_dd_EXECUTABLE}" ARGS if=/dev/zero of=lindows_c.img bs=1M count=512 # format disk with new NTFS filesystem COMMAND "${NTFS3g_Mkfs_EXECUTABLE}" ARGS -F # scary! -L Windows ./lindows_c.img # mount filesystem COMMAND "${NTFS3g_Mount_EXECUTABLE}" ARGS -o no_def_opts lindows_c.img lindows_c # create system folders COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/System32 COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/System32/LNXConfig COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/System32/Config COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/GRUB COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Windows/GRUB/x86_64-efi COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS 'lindows_c/Windows/Temporary Files' # grub stuff COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS ${CMAKE_CURRENT_BINARY_DIR}/grub/lib/grub/x86_64-efi/* lindows_c/Windows/GRUB/x86_64-efi COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/src/grub/grub.cfg lindows_c/Windows/GRUB/grub.cfg # install the kernel COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS ${CMAKE_CURRENT_BINARY_DIR}/linux/bzImage lindows_c/Windows/vmlinux.exe # copy glibc files to system32 COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copylib glibc COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/src/glibc/ld.so.conf lindows_c/Windows/System32/LNXConfig/ld.so.conf # copy bash to system32 COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copylib bash # copy curses to system32 COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copylib ncurses # continuedd COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copylib gcc lib64 # copy lindows binaries COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/lsmss.exe COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/lrss.exe COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/liblrssclient.so COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/lexecutive.exe COMMAND ${CoreUtils_Copy_EXECUTABLE} ARGS $ lindows_c/Windows/System32/lcrash.exe # create registry hives COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mkhive lindows_c/Windows/System32/Config/System COMMAND hivexsh lindows_c/Windows/System32/Config/System -w -f ${CMAKE_CURRENT_SOURCE_DIR}/scripts/hivex/system.hivex # create users folder COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Users # unmount filesystem COMMAND "umount" ARGS lindows_c DEPENDS lexecutive lcrash lsmss lrss lrssclient Linux-install GLibC-install Bash-install NCurses-install LinuxKernel src/grub/grub.cfg src/glibc/ld.so.conf scripts/copylib scripts/mkhive scripts/hivex/system.hivex ) # this makes the efi system partition add_custom_command(OUTPUT lindows_efi.img COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS -p lindows_efi/ COMMAND "${CMAKE_CURRENT_BINARY_DIR}/grub/bin/grub-mkimage" ARGS -p /Windows/GRUB -O x86_64-efi -o lindows_efi/grubx64.efi -c ${CMAKE_CURRENT_SOURCE_DIR}/src/grub/grub-early.cfg part_gpt ntfs COMMAND "${CoreUtils_dd_EXECUTABLE}" ARGS if=/dev/zero of=lindows_efi.img bs=1M count=33 #COMMAND mkfs.vfat lindows_efi.img -F 32 COMMAND ${MTools_Format_EXECUTABLE} -i lindows_efi.img COMMAND ${MTools_Mkdir_EXECUTABLE} -i lindows_efi.img ::/EFI COMMAND ${MTools_Mkdir_EXECUTABLE} -i lindows_efi.img ::/EFI/BOOT COMMAND ${MTools_Copy_EXECUTABLE} -i lindows_efi.img lindows_efi/grubx64.efi ::/EFI/BOOT/BOOTX64.EFI DEPENDS src/grub/grub-early.cfg ) # make the full disk image add_custom_command(OUTPUT lindows.img COMMAND echo ARGS label: gpt > disk.sfdisk COMMAND echo ARGS unit: sectors >> disk.sfdisk COMMAND echo ARGS start=1MiB, size=33MiB, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B >> disk.sfdisk COMMAND echo ARGS start=34MiB, size=512MiB, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, uuid=48D29DA8-2FF8-4F23-BA1A-0E8CCFC329E2 >> disk.sfdisk COMMAND "${CoreUtils_dd_EXECUTABLE}" ARGS if=/dev/zero of=lindows.img bs=1M count=600 # partition disk COMMAND sfdisk ARGS lindows.img < disk.sfdisk # write partitions COMMAND "${CoreUtils_dd_EXECUTABLE}" ARGS if=lindows_efi.img of=lindows.img bs=1M count=33 seek=1 conv=notrunc COMMAND "${CoreUtils_dd_EXECUTABLE}" ARGS if=lindows_c.img of=lindows.img bs=1M count=512 seek=34 conv=notrunc DEPENDS lindows_c.img lindows_efi.img BYPRODUCTS disk.sfdisk ) add_custom_target(lindows ALL DEPENDS lindows.img) add_subdirectory(executive) add_subdirectory(lsmss) add_subdirectory(lrss) add_subdirectory(lcrash)