最外层


最外层

cmake_minimum_required(VERSION 3.14)
project (myproject VERSION 0.1.0)

configure_file(src/utils/version_config.h.in utils/version_config.h)
add_definitions(-DVERSION_SUFFIX=\"alpha\")

# path
set(TOP_DIR ${CMAKE_CURRENT_LIST_DIR})

# cxx flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -std=c++17 -fPIC")

# enable the -O2 option only in release mode
if(CMAKE_BUILD_TYPE MATCHES "Release")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
endif()

# include dependencies
include(cmake/utils.cmake)
include(cmake/dependency_glog.cmake)
include(cmake/dependency_json.cmake)
include(cmake/dependency_gtest.cmake)
include(cmake/dependency_zstd.cmake)
include(cmake/dependency_securec.cmake)
include(cmake/dependency_parser.cmake)
include(cmake/dependency_protobuf.cmake)
include(cmake/dependency_tinyxml2.cmake)
include(cmake/dependency_gflags.cmake)

# get git hash
set(GIT_HASH "")
get_git_hash(GIT_HASH)
add_definitions(-DGIT_HASH=\"${GIT_HASH}\")

# set the optimization option to -O0
if(ENABLE_COVERAGE)
    add_compile_options("-O0")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
endif()

# set asan option
if(ENABLE_ASAN)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
    if(ASAN_RECOVER)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize-recover=address")
    endif()
    unset(ASAN_RECOVER CACHE)
endif()
unset(ENABLE_ASAN CACHE)

# set profile definitions
if(ENABLE_LINEAR_PROFILE)
    add_definitions(-DENABLE_LINEAR_PROFILE)
endif()
unset(ENABLE_LINEAR_PROFILE CACHE)

if(ENABLE_STORAGE_PROFILE)
    add_definitions(-DENABLE_STORAGE_PROFILE)
endif()
unset(ENABLE_STORAGE_PROFILE CACHE)

if(ENABLE_TOP_PROFILE)
    add_definitions(-DENABLE_TOP_PROFILE)
endif()
unset(ENABLE_TOP_PROFILE CACHE)

option(ASSERT_DEBUG_MODE "wether to use ASSERT_DEBUG_MODE" off)
if(ASSERT_DEBUG_MODE)
add_definitions(-DASSERT_DEBUG_MODE)
endif()
unset(ASSERT_DEBUG_MODE CACHE)

option(UT_TEST_MODE "running ut test" off)
if(UT_TEST_MODE)
add_definitions(-DUT_TEST_MODE)
endif()
unset(UT_TEST_MODE CACHE)

# src
include_directories(src)
include_directories(include)
add_subdirectory(src)

# tests
if(ENABLE_TESTCASES)
    add_subdirectory(tests)
endif()
if(ENABLE_TESTSIV)
    add_subdirectory(siv_test)
endif()

src层

set(SRC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")

include_directories(${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/src/backend)
include_directories(${CMAKE_SOURCE_DIR}/src/dm)
include_directories(${CMAKE_SOURCE_DIR}/src/utils)
include_directories(${CMAKE_SOURCE_DIR}/src/extension)
include_directories(${CMAKE_SOURCE_DIR}/src/runtime)

include_directories(myproject PRIVATE "../third_party/parser/lef")
include_directories(myproject PRIVATE "../third_party/parser/def")
include_directories(myproject PRIVATE "../third_party/gds2/include")
include_directories(myproject PRIVATE "../third_party/gds2/src")
include_directories(myproject PRIVATE "parser/")
include_directories(myproject PRIVATE "parser/translator")

add_subdirectory(backend)
add_subdirectory(dm)
add_subdirectory(parser)
add_subdirectory(utils)
add_subdirectory(extension)
add_subdirectory(runtime)

# create lib
add_library(myproject_lib STATIC
                  $<TARGET_OBJECTS:_utils>
                  $<TARGET_OBJECTS:glog::glog>
                  $<TARGET_OBJECTS:gflags::gflags>
                  $<TARGET_OBJECTS:_tech>
                  $<TARGET_OBJECTS:_data_container>
                  $<TARGET_OBJECTS:lef>
                  $<TARGET_OBJECTS:def>
                  $<TARGET_OBJECTS:gds2>
                  $<TARGET_OBJECTS:_common>
                  $<TARGET_OBJECTS:_design>
                  $<TARGET_OBJECTS:_parser>
                  $<TARGET_OBJECTS:libprotobuf>
                  $<TARGET_OBJECTS:_mem>
                  $<TARGET_OBJECTS:tinyxml2>
                  $<TARGET_OBJECTS:_plugin>
                  $<TARGET_OBJECTS:_design_template>
                  $<TARGET_OBJECTS:_persistence>
                  $<TARGET_OBJECTS:_runtime>
                  $<TARGET_OBJECTS:securec>
                  $<TARGET_OBJECTS:jsoncpp_static>
                  $<TARGET_OBJECTS:libzstd_static>
                  )
add_dependencies(myproject_lib _persistence)
target_link_libraries(myproject_lib PUBLIC
  -static
  -Wl,--whole-archive
  -lpthread
  -lstdc++fs
  -ldl
  -lz
  -Wl,--no-whole-archive
)
set_target_properties(myproject_lib PROPERTIES OUTPUT_NAME "myproject")

# create so
add_library(myproject_so SHARED
              $<TARGET_OBJECTS:_utils>
              $<TARGET_OBJECTS:glog::glog>
              $<TARGET_OBJECTS:gflags::gflags>
              $<TARGET_OBJECTS:_tech>
              $<TARGET_OBJECTS:_data_container>
              $<TARGET_OBJECTS:lef>
              $<TARGET_OBJECTS:def>
              $<TARGET_OBJECTS:gds2>
              $<TARGET_OBJECTS:_common>
              $<TARGET_OBJECTS:_design>
              $<TARGET_OBJECTS:_parser>
              $<TARGET_OBJECTS:libprotobuf>
              $<TARGET_OBJECTS:_mem>
              $<TARGET_OBJECTS:tinyxml2>
              $<TARGET_OBJECTS:_plugin>
              $<TARGET_OBJECTS:_design_template>
              $<TARGET_OBJECTS:_persistence>
              $<TARGET_OBJECTS:_runtime>
              $<TARGET_OBJECTS:securec>
              $<TARGET_OBJECTS:jsoncpp_object>
              $<TARGET_OBJECTS:libzstd_shared>
)
add_dependencies(myproject_so _persistence)
target_link_libraries(myproject_so PUBLIC
  -Wl,--whole-archive
  -lpthread
  -lstdc++fs
  -ldl
  -lz
  -Wl,--no-whole-archive
)
set_target_properties(myproject_so PROPERTIES OUTPUT_NAME "myproject")

src内部的具体模块

aux_source_directory(. _MEM_SOURCE_LIST)
add_library(_mem SHARED ${_MEM_SOURCE_LIST})
add_dependencies(_mem _persistence)
set_target_build_dir(_mem)
target_include_directories( _mem PRIVATE ${SRC_ROOT}/backend)
target_include_directories( _mem PRIVATE ${SRC_ROOT}/dm)
target_include_directories( _mem PRIVATE ${SRC_ROOT}/utils)

使用这些库的可执行文件

message("build st testcases...")

# virtual project for common include and library file path.
project(st)

include_directories(${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/src/backend)
include_directories(${CMAKE_SOURCE_DIR}/src/dm)
include_directories(${CMAKE_SOURCE_DIR}/src/parser)
include_directories(${CMAKE_SOURCE_DIR}/src/extension)

include_directories(st_tests PRIVATE "../../../src/backend")
include_directories(st_tests PRIVATE "../../../src/backend/persistence")
include_directories(st_tests PRIVATE "../../../src/dm")
include_directories(st_tests PRIVATE "../../../src/parser/translator")
include_directories(st_tests PRIVATE "../../../src/parser/gds2")
include_directories(st_tests PRIVATE "../../../src/utils")
include_directories(st_tests PRIVATE "../../../third_party/parser/lef")
include_directories(st_tests PRIVATE "../../../third_party/parser/def")
include_directories(st_tests PRIVATE "../../../third_party/gds2")
include_directories(st_tests PRIVATE ${CMAKE_BINARY_DIR})

MESSAGE("check source ${CMAKE_SOURCE_DIR}")
MESSAGE("check st_test ${CMAKE_CURRENT_SOURCE_DIR}")

file(GLOB_RECURSE ST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
    "../translator/*.cc"
    "./common/*.cc"
    )

add_executable(st_tests ${ST_SRCS})
target_link_libraries(st_tests PRIVATE
  -Wl,--start-group
  -ldl
  gflags
  gtest
  glog
  libprotobuf
  _parser
  gds2
  securec
  _common
  _design
  _mem
  _utils
  _persistence
  _data_container
  _tech
  _plugin
  tinyxml2
  _design_template
  lef
  def
  stdc++fs
  -Wl,--end-group
  )

add_subdirectory(gds2txt)

每次构建还需要build.sh的配合

#!/bin/bash

set -e
BASEPATH=$(cd "$(dirname $0)"; pwd)
export BUILD_PATH="${BASEPATH}/build"

_COUNT=0

define_opt() {
  local var=$1
  local default=$2
  local opt=$3
  local flag=$4
  local intro=$5

  # count opt number
  _COUNT=$((${_COUNT} + 1))

  local max_flag=8
  local mod_max=$((${_COUNT} % ${max_flag}))
  local flag_space="              "
  local intro_space="     "

  # set global varible
  if [[ "X${var}" != "X" ]] && [[ "X${default}" != "X" ]]; then
      eval "${var}=${default}"
  fi
  _OPTS="${_OPTS}${opt}"
  if [[ "X${mod_max}" != "X1" ]] && [[ "X${mod_max}" != "X${_COUNT}" ]]; then
      _FLAGS="${_FLAGS}\n${flag_space}[${flag}]"
  else
      _FLAGS="${_FLAGS} [${flag}]"
  fi
  _INTROS="${_INTROS}${intro_space}${flag} ${intro}\n"
}

# define option
define_opt ""                ""                   "h"  "-h"                     "Print usage"
define_opt DEBUG_MODE        "off"                "d"  "-d"                     "Enable debug mode, default off"
define_opt VERBOSE_MODE      "off"                "v"  "-v"                     "Enable building verbose mode, defalut off"
define_opt GEN_COVERAGE      "off"                "c"  "-c"                     "Generate coverage information, default off"
define_opt ENABLE_TESTS      "off"                "t"  "-t"                     "Enable running test cases, default off"
define_opt ENABLE_SIV        "off"                "s"  "-s"                     "Enable running siv test cases, default off"
define_opt THREAD_NUM        8                    "j:" "-j[n]"                  "Set the threads number when building, default 8"
define_opt CREAT_LOGFILE     "off"                "f"  "-f"                     "Creat Log File, default off"
define_opt INC_BUILD         "off"                "i"  "-i"                     "Enable incremental building, default off"
define_opt ENABLE_PROFILE    "st"                 "p:" "-p[opt]"                "Enable profile, opt l for linear time profile, s for storage profile, t for top time profile, default st"
define_opt ENABLE_ASAN       "off"                "a"  "-a"                     "Enable address sanitizer (ASAN), default off"
define_opt ASAN_RECOVER      "off"                "r"  "-r"                     "Enable error recover mode for ASAN, only valid when used with -a option"

# print usage message
usage()
{
  printf "Usage:\nbash build.sh${_FLAGS}\n\n"
  printf "Options:\n${_INTROS}"
}

# check value of input is 'on' or 'off'
# usage: check_on_off arg_value arg_name
check_on_off()
{
  if [[ "X$1" != "Xon" && "X$1" != "Xoff" ]]; then
    echo "Invalid value $1 for option -$2"
    usage
    exit 1
  fi
}

# check and set options
checkopts()
{
  # process the options
  while getopts "${_OPTS}" opt
  do
    OPTARG=$(echo ${OPTARG} | tr '[A-Z]' '[a-z]')
    case "${opt}" in
      v)
        VERBOSE_MODE="on"
        ;;
      d)
        DEBUG_MODE="on"
        ;;
      j)
        THREAD_NUM=$OPTARG
        ;;
      c)
        GEN_COVERAGE="on"
        ;;
      t)
        ENABLE_TESTS="on"
        ;;
      i)
        INC_BUILD="on"
        ;;
      f)
        CREAT_LOGFILE="on"
        ;;
      s)
        ENABLE_SIV="on"
        ;;
      p)
        ENABLE_PROFILE=$OPTARG
        ;;
      a)
        ENABLE_ASAN="on"
        ;;
      r)
        ASAN_RECOVER="on"
        ;;
      h)
        usage
        exit 0
        ;;
      *)
        echo "Unknown option ${opt}!"
        usage
        exit 1
    esac
  done
}

checkopts "$@"
echo "---------------- myproject: build start ----------------"
git submodule update --init --recursive

build_exit()
{
    echo "$@" >&2
    stty echo
    exit 1
}

# define path
export DB_BUILD_PATH="${BUILD_PATH}/myproject/"
export DB_BUILD_BIN_PATH="${BUILD_PATH}/myproject/bin/"
export DB_BUILD_LIB_PATH="${BUILD_PATH}/myproject/lib"
export DB_OUTPUT_PATH="${BASEPATH}/output/"
export DB_OUTPUT_LIB_PATH="${BASEPATH}/output/lib/"
export DB_OUTPUT_SO_PATH="${BASEPATH}/output/so/"
export DB_OUTPUT_DEPENDS_PATH="${BASEPATH}/output/deps/"
export DB_OUTPUT_LOG_PATH="${BASEPATH}/log/"

build_myproject()
{
    echo "start build myproject project."
    mkdir -pv ${DB_BUILD_PATH}
    mkdir -pv ${DB_OUTPUT_LIB_PATH}
    mkdir -pv ${DB_OUTPUT_SO_PATH}
    mkdir -pv ${DB_OUTPUT_LOG_PATH}

    cd ${DB_BUILD_PATH}

    CMAKE_ARGS="-DDEBUG_MODE=$DEBUG_MODE"
    if [[ "X$ENABLE_TESTS" = "Xon" ]]; then
      CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_TESTCASES=ON"
      CMAKE_ARGS="${CMAKE_ARGS} -DUT_TEST_MODE=ON"
    fi

    if [[ "X$ENABLE_SIV" = "Xon" ]]; then
      CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_TESTSIV=ON"
    fi

    if [[ "X$GEN_COVERAGE" = "Xon" ]]; then
      CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_COVERAGE=ON"
    fi

    if [[ "X$CREAT_LOGFILE" = "Xon" ]]; then
      CMAKE_ARGS="${CMAKE_ARGS} -DCREAT_LOGFILE=ON"
      CMAKE_ARGS="${CMAKE_ARGS} -DDB_OUTPUT_LOG_PATH=${BASEPATH}/log/"
    fi

    if [[ "X$ENABLE_ASAN" = "Xon" ]]; then
      CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_ASAN=ON"
      if [[ "X$ASAN_RECOVER" = "Xon" ]]; then
        CMAKE_ARGS="${CMAKE_ARGS} -DASAN_RECOVER=ON"
      fi
    fi

    if [[ "$ENABLE_PROFILE" =~ "l" ]]; then
      CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_LINEAR_PROFILE=ON"
    fi
    if [[ "$ENABLE_PROFILE" =~ "s" ]]; then
      CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_STORAGE_PROFILE=ON"
    fi
    if [[ "$ENABLE_PROFILE" =~ "t" ]]; then
      CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_TOP_PROFILE=ON"
    fi

    if [[ "X$DEBUG_MODE" = "Xoff" ]]; then
      CMAKE_ARGS="${CMAKE_ARGS} -DCMAKE_BUILD_TYPE=Release"
    else
      CMAKE_ARGS="${CMAKE_ARGS} -DCMAKE_BUILD_TYPE=Debug"
      CMAKE_ARGS="${CMAKE_ARGS} -DLOG_DEBUG_MODE=ON"
      CMAKE_ARGS="${CMAKE_ARGS} -DASSERT_DEBUG_MODE=ON"
    fi

    echo "${CMAKE_ARGS}"
    if [[ "X$INC_BUILD" = "Xoff" ]]; then
      cmake ${CMAKE_ARGS} ${BASEPATH}
    fi

    if [[ "X$VERBOSE_MODE" = "Xon" ]]; then
      CMAKE_VERBOSE="--verbose"
    fi

    cmake --build . ${CMAKE_VERBOSE} -j$THREAD_NUM

    rm ${BASEPATH}/third_party/parser/lef/lef/lef.tab.*
    rm ${BASEPATH}/third_party/parser/def/def/def.tab.*

    ln -sf ${DB_BUILD_BIN_PATH} ${DB_OUTPUT_PATH}
    ln -sf ${DB_BUILD_LIB_PATH}/libmyproject.a ${DB_OUTPUT_LIB_PATH}
    ln -sf ${DB_BUILD_LIB_PATH}/libmyproject.so ${DB_OUTPUT_SO_PATH}

    echo "success building myproject project!"
}

build_myproject

echo "---------------- myproject: build end   ----------------"