From 56129d26ebd8c54563e92a78b9dab20f69dbc646 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 19 Aug 2022 22:06:15 -0700 Subject: [PATCH] cmake: build stage3 by default This is a simplification of the cmake build script which introduces a new "stage3" target that is built by default, which builds and installs a stage3 zig. It greatly simplifies the build instructions for Zig, making it conform to the regular cmake routine, while still producing a stage3 artifact. --- CMakeLists.txt | 134 +++++++++++++-------------- ci/zinc/linux_test_stage3_debug.sh | 23 ++--- ci/zinc/linux_test_stage3_release.sh | 35 +------ cmake/install.cmake | 37 -------- 4 files changed, 81 insertions(+), 148 deletions(-) delete mode 100644 cmake/install.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index d9784090cd..f50d8b48dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ if(NOT CMAKE_BUILD_TYPE) endif() if(NOT CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/stage2" CACHE STRING + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/stage3" CACHE STRING "Directory to install zig to" FORCE) endif() @@ -65,6 +65,9 @@ if("${ZIG_VERSION}" STREQUAL "") endif() message(STATUS "Configuring zig version ${ZIG_VERSION}") +set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL + "Disable copying lib/ files to install prefix during the build phase") + set(ZIG_STATIC off CACHE BOOL "Attempt to build a static zig executable (not compatible with glibc)") set(ZIG_SHARED_LLVM off CACHE BOOL "Prefer linking against shared LLVM libraries") set(ZIG_STATIC_LLVM off CACHE BOOL "Prefer linking against static LLVM libraries") @@ -333,7 +336,7 @@ set(ZIG_CONFIG_H_OUT "${CMAKE_BINARY_DIR}/config.h") set(ZIG_CONFIG_ZIG_OUT "${CMAKE_BINARY_DIR}/config.zig") # This is our shim which will be replaced by stage1.zig. -set(ZIG0_SOURCES +set(ZIG1_SOURCES "${CMAKE_SOURCE_DIR}/src/stage1/zig0.cpp" ) @@ -373,9 +376,9 @@ set(ZIG_CPP_SOURCES # https://github.com/ziglang/zig/issues/6363 "${CMAKE_SOURCE_DIR}/src/windows_sdk.cpp" ) -# Needed because we use cmake, not the zig build system, to build zig1.o. +# Needed because we use cmake, not the zig build system, to build zig2.o. # This list is generated by building zig and then clearing the zig-cache directory, -# then manually running the build-obj command (see BUILD_ZIG1_ARGS), and then looking +# then manually running the build-obj command (see BUILD_ZIG2_ARGS), and then looking # in the zig-cache directory for the compiler-generated list of zig file dependencies. set(ZIG_STAGE2_SOURCES "${ZIG_CONFIG_ZIG_OUT}" @@ -942,40 +945,47 @@ if(MSVC OR MINGW) endif() if("${ZIG_EXECUTABLE}" STREQUAL "") - add_executable(zig0 ${ZIG0_SOURCES}) - set_target_properties(zig0 PROPERTIES + add_executable(zig1 ${ZIG1_SOURCES}) + set_target_properties(zig1 PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} LINK_FLAGS ${EXE_LDFLAGS} ) - target_link_libraries(zig0 zigstage1) + target_link_libraries(zig1 zigstage1) endif() if(MSVC) - set(ZIG1_OBJECT "${CMAKE_BINARY_DIR}/zig1.obj") + set(ZIG2_OBJECT "${CMAKE_BINARY_DIR}/zig2.obj") else() - set(ZIG1_OBJECT "${CMAKE_BINARY_DIR}/zig1.o") + set(ZIG2_OBJECT "${CMAKE_BINARY_DIR}/zig2.o") endif() if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - set(ZIG1_RELEASE_ARG "") + set(ZIG_RELEASE_ARG "") else() - set(ZIG1_RELEASE_ARG -OReleaseFast --strip) + set(ZIG_RELEASE_ARG -Drelease) +endif() +if(ZIG_SKIP_INSTALL_LIB_FILES) + set(ZIG_SKIP_INSTALL_LIB_FILES_ARG "-Dskip-install-lib-files") +else() + set(ZIG_SKIP_INSTALL_LIB_FILES_ARG "-Dskip-install-lib-files=false") endif() if(ZIG_SINGLE_THREADED) - set(ZIG1_SINGLE_THREADED_ARG "-fsingle-threaded") + set(ZIG_SINGLE_THREADED_ARG "-fsingle-threaded") else() - set(ZIG1_SINGLE_THREADED_ARG "") + set(ZIG_SINGLE_THREADED_ARG "") +endif() +if(ZIG_STATIC) + set(ZIG_STATIC_ARG "-Duse-zig-libcxx") +else() + set(ZIG_STATIC_ARG "") endif() -set(BUILD_ZIG1_ARGS +set(BUILD_ZIG2_ARGS "src/stage1.zig" - -target "${ZIG_TARGET_TRIPLE}" - "-mcpu=${ZIG_TARGET_MCPU}" - --name zig1 + --name zig2 --zig-lib-dir "${CMAKE_SOURCE_DIR}/lib" - "-femit-bin=${ZIG1_OBJECT}" + "-femit-bin=${ZIG2_OBJECT}" -fcompiler-rt - "${ZIG1_RELEASE_ARG}" - "${ZIG1_SINGLE_THREADED_ARG}" + "${ZIG_SINGLE_THREADED_ARG}" -lc --pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}" --pkg-end @@ -985,68 +995,58 @@ set(BUILD_ZIG1_ARGS if("${ZIG_EXECUTABLE}" STREQUAL "") add_custom_command( - OUTPUT "${ZIG1_OBJECT}" - COMMAND zig0 ${BUILD_ZIG1_ARGS} - DEPENDS zig0 "${ZIG_STAGE2_SOURCES}" - COMMENT STATUS "Building self-hosted component ${ZIG1_OBJECT}" - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT "${ZIG2_OBJECT}" + COMMAND zig1 ${BUILD_ZIG2_ARGS} + DEPENDS zig1 "${ZIG_STAGE2_SOURCES}" + COMMENT STATUS "Building stage2 object ${ZIG2_OBJECT}" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" ) - set(ZIG_EXECUTABLE "${zig_BINARY_DIR}/zig") if (WIN32) - set(ZIG_EXECUTABLE "${ZIG_EXECUTABLE}.exe") + set(ZIG_EXECUTABLE "${zig2_BINARY_DIR}/zig2.exe") + else() + set(ZIG_EXECUTABLE "${zig2_BINARY_DIR}/zig2") endif() else() add_custom_command( - OUTPUT "${ZIG1_OBJECT}" - COMMAND "${ZIG_EXECUTABLE}" "build-obj" ${BUILD_ZIG1_ARGS} - DEPENDS ${ZIG_STAGE2_SOURCES} - COMMENT STATUS "Building self-hosted component ${ZIG1_OBJECT}" - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT "${ZIG2_OBJECT}" + COMMAND "${ZIG_EXECUTABLE}" "build-obj" ${BUILD_ZIG2_ARGS} + DEPENDS ${ZIG_STAGE2_SOURCES} + COMMENT STATUS "Building stage2 component ${ZIG2_OBJECT}" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" ) endif() # cmake won't let us configure an executable without C sources. -add_executable(zig "${CMAKE_SOURCE_DIR}/src/stage1/empty.cpp" "${ZIG1_OBJECT}") +add_executable(zig2 "${CMAKE_SOURCE_DIR}/src/stage1/empty.cpp" "${ZIG2_OBJECT}") -set_target_properties(zig PROPERTIES +set_target_properties(zig2 PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} LINK_FLAGS ${EXE_LDFLAGS} ) -target_link_libraries(zig zigstage1) +target_link_libraries(zig2 zigstage1) if(MSVC) - target_link_libraries(zig ntdll.lib) + target_link_libraries(zig2 ntdll.lib) elseif(MINGW) - target_link_libraries(zig ntdll) + target_link_libraries(zig2 ntdll) endif() -install(TARGETS zig DESTINATION bin) +set(ZIG_INSTALL_ARGS "build" + --zig-lib-dir "${CMAKE_SOURCE_DIR}/lib" + --prefix "${CMAKE_INSTALL_PREFIX}" + "-Dconfig_h=${ZIG_CONFIG_H_OUT}" + "-Denable-llvm" + "-Denable-stage1" + "${ZIG_RELEASE_ARG}" + "${ZIG_STATIC_ARG}" + "${ZIG_SKIP_INSTALL_LIB_FILES_ARG}" + "${ZIG_SINGLE_THREADED_ARG}" + "-Dtarget=${ZIG_TARGET_TRIPLE}" + "-Dcpu=${ZIG_TARGET_MCPU}" +) -set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL - "Disable copying lib/ files to install prefix during the build phase") - -if(NOT ZIG_SKIP_INSTALL_LIB_FILES) - set(ZIG_INSTALL_ARGS "build" - --zig-lib-dir "${CMAKE_SOURCE_DIR}/lib" - "-Dlib-files-only" - --prefix "${CMAKE_INSTALL_PREFIX}" - "-Dconfig_h=${ZIG_CONFIG_H_OUT}" - install - ) - - # CODE has no effect with Visual Studio build system generator, therefore - # when using Visual Studio build system generator we resort to running - # `zig build install` during the build phase. - if(MSVC) - add_custom_target(zig_install_lib_files ALL - COMMAND zig ${ZIG_INSTALL_ARGS} - DEPENDS zig - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - ) - else() - get_target_property(zig_BINARY_DIR zig BINARY_DIR) - install(CODE "set(zig_EXE \"${ZIG_EXECUTABLE}\")") - install(CODE "set(ZIG_INSTALL_ARGS \"${ZIG_INSTALL_ARGS}\")") - install(CODE "set(CMAKE_SOURCE_DIR \"${CMAKE_SOURCE_DIR}\")") - install(SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/cmake/install.cmake) - endif() -endif() +add_custom_target(stage3 ALL + COMMAND zig2 ${ZIG_INSTALL_ARGS} + DEPENDS zig2 + COMMENT STATUS "Building stage3" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" +) diff --git a/ci/zinc/linux_test_stage3_debug.sh b/ci/zinc/linux_test_stage3_debug.sh index ba33311a4d..ccfa698765 100755 --- a/ci/zinc/linux_test_stage3_debug.sh +++ b/ci/zinc/linux_test_stage3_debug.sh @@ -20,12 +20,11 @@ export CXX="$OLD_ZIG c++ -target $TARGET -mcpu=$MCPU" mkdir build-debug cd build-debug cmake .. \ - -DCMAKE_INSTALL_PREFIX="$DEBUG_STAGING" \ + -DCMAKE_INSTALL_PREFIX="$(pwd)/stage3" \ -DCMAKE_PREFIX_PATH="$DEPS_LOCAL" \ -DCMAKE_BUILD_TYPE=Debug \ - -DZIG_TARGET_TRIPLE="$TARGET" \ - -DZIG_TARGET_MCPU="$MCPU" \ -DZIG_STATIC=ON \ + -DZIG_USE_LLVM_CONFIG=OFF \ -GNinja # Now cmake will use zig as the C/C++ compiler. We reset the environment variables @@ -35,21 +34,17 @@ unset CXX ninja install -cd $WORKSPACE - -"$DEBUG_STAGING/bin/zig" build -p stage3 -Denable-stage1 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL" +echo "Looking for non-conforming code formatting..." +stage3/bin/zig fmt --check .. \ + --exclude ../test/cases/ \ + --exclude ../build-debug \ + --exclude ../build-release \ + --exclude "$ZIG_LOCAL_CACHE_DIR" \ + --exclude "$ZIG_GLOBAL_CACHE_DIR" # simultaneously test building self-hosted without LLVM and with 32-bit arm stage3/bin/zig build -Dtarget=arm-linux-musleabihf -echo "Looking for non-conforming code formatting..." -stage3/bin/zig fmt --check . \ - --exclude test/cases/ \ - --exclude build-debug \ - --exclude build-release \ - --exclude "$ZIG_LOCAL_CACHE_DIR" \ - --exclude "$ZIG_GLOBAL_CACHE_DIR" - stage3/bin/zig build test \ -fqemu \ -fwasmtime \ diff --git a/ci/zinc/linux_test_stage3_release.sh b/ci/zinc/linux_test_stage3_release.sh index 3f330cf548..2758ea9ca3 100755 --- a/ci/zinc/linux_test_stage3_release.sh +++ b/ci/zinc/linux_test_stage3_release.sh @@ -13,9 +13,8 @@ export CXX="$OLD_ZIG c++ -target $TARGET -mcpu=$MCPU" mkdir build-release cd build-release -STAGE2_PREFIX="$(pwd)/stage2" cmake .. \ - -DCMAKE_INSTALL_PREFIX="$STAGE2_PREFIX" \ + -DCMAKE_INSTALL_PREFIX="$RELEASE_STAGING" \ -DCMAKE_PREFIX_PATH="$DEPS_LOCAL" \ -DCMAKE_BUILD_TYPE=Release \ -DZIG_TARGET_TRIPLE="$TARGET" \ @@ -30,31 +29,7 @@ unset CXX ninja install -# Here we rebuild zig but this time using the Zig binary we just now produced to -# build zig1.o rather than relying on the one built with stage0. See -# https://github.com/ziglang/zig/issues/6830 for more details. -cmake .. -DZIG_EXECUTABLE="$STAGE2_PREFIX/bin/zig" -ninja install - -# This is the binary we will distribute. We intentionally test this one in this -# script. If any test failures occur, hopefully they also occur in the debug -# version of this script for easier troubleshooting. This prevents distribution -# of a Zig binary that passes tests in debug mode but has a miscompilation in -# release mode. -"$STAGE2_PREFIX/bin/zig" build \ - --prefix "$RELEASE_STAGING" \ - --search-prefix "$DEPS_LOCAL" \ - -Dstatic-llvm \ - -Drelease \ - -Dstrip \ - -Dtarget="$TARGET" \ - -Denable-stage1 - -cd $WORKSPACE - -ZIG="$RELEASE_STAGING/bin/zig" - -$ZIG build test docs \ +"$RELEASE_STAGING/bin/zig" build test docs \ -fqemu \ -fwasmtime \ -Dstatic-llvm \ @@ -63,13 +38,13 @@ $ZIG build test docs \ # Produce the experimental std lib documentation. mkdir -p "$RELEASE_STAGING/docs/std" -$ZIG test lib/std/std.zig \ +"$RELEASE_STAGING/bin/zig" test ../lib/std/std.zig \ --zig-lib-dir lib \ -femit-docs=$RELEASE_STAGING/docs/std \ -fno-emit-bin -cp LICENSE $RELEASE_STAGING/ -cp zig-cache/langref.html $RELEASE_STAGING/docs/ +cp ../LICENSE $RELEASE_STAGING/ +cp ../zig-cache/langref.html $RELEASE_STAGING/docs/ # Look for HTML errors. tidy --drop-empty-elements no -qe $RELEASE_STAGING/docs/langref.html diff --git a/cmake/install.cmake b/cmake/install.cmake deleted file mode 100644 index 386773e30c..0000000000 --- a/cmake/install.cmake +++ /dev/null @@ -1,37 +0,0 @@ -message("-- Installing: ${CMAKE_INSTALL_PREFIX}/lib") - -if(NOT EXISTS ${zig_EXE}) - message("::") - message(":: ERROR: Executable not found") - message(":: (execute_process)") - message("::") - message(":: executable: ${zig_EXE}") - message("::") - message(FATAL_ERROR) -endif() - -execute_process(COMMAND ${zig_EXE} ${ZIG_INSTALL_ARGS} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - RESULT_VARIABLE _result -) -if(_result) - message("::") - message(":: ERROR: ${_result}") - message(":: (execute_process)") - - string(REPLACE ";" " " s_INSTALL_LIBSTAGE2_ARGS "${ZIG_INSTALL_ARGS}") - message("::") - message(":: argv: ${zig_EXE} ${s_INSTALL_LIBSTAGE2_ARGS}") - - set(_args ${zig_EXE} ${ZIG_INSTALL_ARGS}) - list(LENGTH _args _len) - math(EXPR _len "${_len} - 1") - message("::") - foreach(_i RANGE 0 ${_len}) - list(GET _args ${_i} _arg) - message(":: argv[${_i}]: ${_arg}") - endforeach() - - message("::") - message(FATAL_ERROR) -endif()