The-OpenROAD-Project / OpenROAD

OpenROAD's unified application implementing an RTL-to-GDS Flow. Documentation at https://openroad.readthedocs.io/en/latest/
https://theopenroadproject.org/
BSD 3-Clause "New" or "Revised" License
1.64k stars 564 forks source link

CUDD not directly linked against OpenROAD #5603

Open donn opened 3 months ago

donn commented 3 months ago

Describe the bug

Newer versions of OpenSTA require CUDD and links it as follows:

if (CUDD_LIB)
  message(STATUS "CUDD library: ${CUDD_LIB}")
  get_filename_component(CUDD_LIB_DIR "${CUDD_LIB}" PATH)
  get_filename_component(CUDD_LIB_PARENT1 "${CUDD_LIB_DIR}" PATH)
  find_file(CUDD_HEADER cudd.h
    PATHS ${CUDD_LIB_PARENT1} ${CUDD_LIB_PARENT1}/include ${CUDD_LIB_PARENT1}/include/cudd)
  if (CUDD_HEADER)
    get_filename_component(CUDD_INCLUDE "${CUDD_HEADER}" PATH)
    message(STATUS "CUDD header: ${CUDD_HEADER}")
  else()
    message(STATUS "CUDD header: not found")
  endif()
else()
  message(STATUS "CUDD library: not found")
endif()

// …

target_link_libraries(OpenSTA
  Eigen3::Eigen
  ${TCL_LIBRARY}
  ${CMAKE_THREAD_LIBS_INIT}
  ${CUDD_LIB}
  )

This link propagates to OpenROAD when OpenSTA is built as part of OpenROAD, however when USE_SYSTEM_OPENSTA is set and OpenSTA is used as a static library, this link does not propagate and the CUDD symbols are not found.

Expected Behavior

Something similar to the code above should also be in OpenROAD's CMake manifests -- I understand USE_SYSTEM_OPENSTA is something of hassle and I thank you for continuing to support it (it cuts down build times tremendously with caching build systems like Nix.)

Environment

-- The CXX compiler identification is Clang 16.0.6
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /nix/store/c1ib07kj7baid3s3wf5m98hcpbvgs8mk-clang-wrapper-16.0.6/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- OpenROAD version: v2.0-15240-gc95d6a16d
-- System name: Darwin
-- Compiler: Clang 16.0.6
-- Build type: RELEASE
-- Install prefix: /var/empty/local
-- C++ Standard: 17
-- C++ Standard Required: ON
-- C++ Extensions: OFF
-- Found OpenSTA: /nix/store/m5hcixmg1lx51hgbyl5f20x6394xhlc9-opensta/lib/libOpenSTA.a
-- Using OPENSTA_INCLUDE_DIR=/usr/include/sta
-- Using ABC_INCLUDE_DIR=/usr/include/abc
-- TCL library: /nix/store/7cpj5zdlz28y6ipg2h4cw6qagvqycm0i-tcl-8.6.13/lib/libtcl.dylib
-- TCL header: /nix/store/7cpj5zdlz28y6ipg2h4cw6qagvqycm0i-tcl-8.6.13/include/tcl.h
-- TCL readline library: /nix/store/0cwgrwkw5kfshdz7bkqjmhm9clas9fqs-tclreadline-2.3.8/lib/libtclreadline.dylib
-- TCL readline header: /nix/store/0cwgrwkw5kfshdz7bkqjmhm9clas9fqs-tclreadline-2.3.8/include
-- Found SWIG: /nix/store/q6jgc1rpam7xqrylwq6gxq2f3arcmhvs-swig-4.0.2/bin/swig (found suitable version "4.0.2", minimum required is "4.0")
-- Found Boost: /nix/store/67hsz87y3shaq2qsql57w5gg8wih8g2m-boost-1.83.0-dev/lib/cmake/Boost-1.83.0/BoostConfig.cmake (found version "1.83.0")
-- boost: 1.83.0
-- Found Python3: /nix/store/0hhzvkw889bsybhqxy12ky4jx6a95p2d-python3-3.11.9/include/python3.11 (found version "3.11.9") found components: Development Development.Module Development.Embed
-- Found ZLIB: /nix/store/5g9k8zyjv029pw87xf95pci414r8pw8j-zlib-1.3.1/lib/libz.dylib (found version "1.3.1")
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- spdlog: 1.13.0
-- Found BISON: /nix/store/zz65ns9x0hczhhdq74905dk297z29zvn-bison-3.8.2/bin/bison (found version "3.8.2")
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 
-- Found Protobuf: /nix/store/a4n8n8wh80wllzrcgrsi94akgj22417g-protobuf-21.12/lib/libprotobuf.dylib (found version "3.21.12")
-- Found re2: /nix/store/ha95iybvpwxg89q3d7q0453fxccxx6dl-re2-2024-05-01-dev/lib/cmake/re2/re2Config.cmake (found version "11.0.0")
-- Found GLPK: /nix/store/zv2pdp1np8n19qgzk0x10kdp2pwfahja-glpk-5.0/lib/libglpk.dylib
-- Found OpenMP_CXX: -fopenmp=libomp (found version "5.0")
-- Found OpenMP: TRUE (found version "5.0")
-- TCL library: /nix/store/7cpj5zdlz28y6ipg2h4cw6qagvqycm0i-tcl-8.6.13/lib/libtcl.dylib
-- TCL header: /nix/store/7cpj5zdlz28y6ipg2h4cw6qagvqycm0i-tcl-8.6.13/include/tcl.h
-- The C compiler identification is Clang 16.0.6
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /nix/store/c1ib07kj7baid3s3wf5m98hcpbvgs8mk-clang-wrapper-16.0.6/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found OpenMP_C: -fopenmp=libomp (found version "5.0")
-- Found OpenMP: TRUE (found version "5.0")
-- Found OpenMP: TRUE (found version "5.0")
-- GUI is enabled
-- Charts widget is enabled
-- Found Boost: /nix/store/67hsz87y3shaq2qsql57w5gg8wih8g2m-boost-1.83.0-dev/lib/cmake/Boost-1.83.0/BoostConfig.cmake (found version "1.83.0") found components: serialization
-- Could NOT find VTune (missing: VTune_LIBRARIES VTune_INCLUDE_DIRS) 
-- Found Boost: /nix/store/67hsz87y3shaq2qsql57w5gg8wih8g2m-boost-1.83.0-dev/lib/cmake/Boost-1.83.0/BoostConfig.cmake (found suitable version "1.83.0", minimum required is "1.78")
-- TCL library: /nix/store/7cpj5zdlz28y6ipg2h4cw6qagvqycm0i-tcl-8.6.13/lib/libtcl.dylib
-- TCL header: /nix/store/7cpj5zdlz28y6ipg2h4cw6qagvqycm0i-tcl-8.6.13/include/tcl.h
-- Found Boost: /nix/store/67hsz87y3shaq2qsql57w5gg8wih8g2m-boost-1.83.0-dev/lib/cmake/Boost-1.83.0/BoostConfig.cmake (found version "1.83.0") found components: serialization system thread
-- Found Eigen3: /nix/store/2arrr3d4ixycdq5lmpqxydz30pip7h7m-eigen-3.4.0/share/eigen3/cmake/Eigen3Config.cmake (found version "3.4.0")
-- TCL readline enabled
-- Tcl Extended disabled
-- Python3 enabled
-- Configuring done (4.4s)
-- Generating done (0.5s)
-- Build files have been written to: /tmp/nix-shell.ytHmRI/tmp.bb9oPZqFpN

To Reproduce

N/A

Relevant log output

Undefined symbols for architecture arm64:
  "_Cudd_Decreasing", referenced from:
      sta::Sim::functionSense(sta::FuncExpr const*, sta::Pin const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
  "_Cudd_E", referenced from:
      sta::Power::evalBddDuty(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
  "_Cudd_Increasing", referenced from:
      sta::Sim::functionSense(sta::FuncExpr const*, sta::Pin const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
  "_Cudd_Init", referenced from:
      sta::Bdd::Bdd(sta::StaState const*) in libOpenSTA.a(Bdd.cc.o)
      sta::Bdd::Bdd(sta::StaState const*) in libOpenSTA.a(Bdd.cc.o)
  "_Cudd_IsConstant", referenced from:
      sta::Power::evalBddDuty(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
  "_Cudd_NodeReadIndex", referenced from:
      sta::Sim::functionSense(sta::FuncExpr const*, sta::Pin const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Sim::funcBddSim(sta::FuncExpr const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Power::evalBddDuty(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::evalBddActivity(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::evalDiffDuty(sta::FuncExpr*, sta::LibertyPort*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::findInputInternalPower(sta::Pin const*, sta::LibertyPort*, sta::Instance const*, sta::LibertyCell*, sta::PwrActivity&, float, sta::Corner const*, sta::PowerResult&) in libOpenSTA.a(Power.cc.o)
      sta::Power::findInputDuty(sta::Instance const*, sta::FuncExpr*, sta::InternalPower*) in libOpenSTA.a(Power.cc.o)
      ...
  "_Cudd_Quit", referenced from:
      sta::Bdd::~Bdd() in libOpenSTA.a(Bdd.cc.o)
      sta::Bdd::~Bdd() in libOpenSTA.a(Bdd.cc.o)
      sta::Bdd::~Bdd() in libOpenSTA.a(Bdd.cc.o)
  "_Cudd_ReadLogicZero", referenced from:
      sta::Sim::funcBddSim(sta::FuncExpr const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Sim::evalExpr(sta::FuncExpr const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Power::evalBddDuty(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Bdd::funcBdd(sta::FuncExpr const*) in libOpenSTA.a(Bdd.cc.o)
  "_Cudd_ReadOne", referenced from:
      sta::Sim::functionSense(sta::FuncExpr const*, sta::Pin const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Sim::funcBddSim(sta::FuncExpr const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Sim::evalExpr(sta::FuncExpr const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Power::evalBddDuty(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Bdd::funcBdd(sta::FuncExpr const*) in libOpenSTA.a(Bdd.cc.o)
  "_Cudd_ReadPerm", referenced from:
      sta::Power::evalBddDuty(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
  "_Cudd_RecursiveDeref", referenced from:
      sta::Sim::functionSense(sta::FuncExpr const*, sta::Pin const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Sim::evalExpr(sta::FuncExpr const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Power::evalActivity(sta::FuncExpr*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::evalBddActivity(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::evalDiffDuty(sta::FuncExpr*, sta::LibertyPort*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::findInputInternalPower(sta::Pin const*, sta::LibertyPort*, sta::Instance const*, sta::LibertyCell*, sta::PwrActivity&, float, sta::Corner const*, sta::PowerResult&) in libOpenSTA.a(Power.cc.o)
      sta::Power::findInputDuty(sta::Instance const*, sta::FuncExpr*, sta::InternalPower*) in libOpenSTA.a(Power.cc.o)
      ...
  "_Cudd_Ref", referenced from:
      sta::Sim::funcBddSim(sta::FuncExpr const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
      sta::Power::evalBddActivity(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::evalDiffDuty(sta::FuncExpr*, sta::LibertyPort*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::findInputInternalPower(sta::Pin const*, sta::LibertyPort*, sta::Instance const*, sta::LibertyCell*, sta::PwrActivity&, float, sta::Corner const*, sta::PowerResult&) in libOpenSTA.a(Power.cc.o)
      sta::Power::findInputDuty(sta::Instance const*, sta::FuncExpr*, sta::InternalPower*) in libOpenSTA.a(Power.cc.o)
      sta::Bdd::funcBdd(sta::FuncExpr const*) in libOpenSTA.a(Bdd.cc.o)
      sta::Bdd::ensureNode(sta::LibertyPort const*) in libOpenSTA.a(Bdd.cc.o)
      ...
  "_Cudd_T", referenced from:
      sta::Power::evalBddDuty(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
  "_Cudd_bddAnd", referenced from:
      sta::Bdd::funcBdd(sta::FuncExpr const*) in libOpenSTA.a(Bdd.cc.o)
  "_Cudd_bddBooleanDiff", referenced from:
      sta::Power::evalBddActivity(DdNode*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::evalDiffDuty(sta::FuncExpr*, sta::LibertyPort*, sta::Instance const*) in libOpenSTA.a(Power.cc.o)
      sta::Power::findInputInternalPower(sta::Pin const*, sta::LibertyPort*, sta::Instance const*, sta::LibertyCell*, sta::PwrActivity&, float, sta::Corner const*, sta::PowerResult&) in libOpenSTA.a(Power.cc.o)
      sta::Power::findInputDuty(sta::Instance const*, sta::FuncExpr*, sta::InternalPower*) in libOpenSTA.a(Power.cc.o)
  "_Cudd_bddCompose", referenced from:
      sta::Sim::funcBddSim(sta::FuncExpr const*, sta::Instance const*) in libOpenSTA.a(Sim.cc.o)
  "_Cudd_bddIthVar", referenced from:
      sta::Bdd::ensureNode(sta::LibertyPort const*) in libOpenSTA.a(Bdd.cc.o)
  "_Cudd_bddOr", referenced from:
      sta::Bdd::funcBdd(sta::FuncExpr const*) in libOpenSTA.a(Bdd.cc.o)
  "_Cudd_bddXor", referenced from:
      sta::Bdd::funcBdd(sta::FuncExpr const*) in libOpenSTA.a(Bdd.cc.o)
ld: symbol(s) not found for architecture arm64
clang-16: error: linker command failed with exit code 1 (use -v to see invocation)

Screenshots

No response

Additional Context

I added my CMake build flags to ./etc/Env.sh as I think they're pertinent in this situation.

jfshorter commented 3 months ago

There at least seems to be existing prescient / intended permission to do so, think it is doable although I'm not much of a CMake magician.

My guess would be to change this out for a shared include for the library detection, similar to patterns used for other libraries, and add the missing conditions for explicit link-only case.

Replace in the original block(s) in src/sta/CMakeList.txt , swap out to use the include. Then special cases in src/CMakeList.txt by adding the include in either the first else() or add a new else case around line 400.

maliberty commented 3 months ago

@donn how urgent is this for you? It might take a bit to get opensta to factor out the cudd cmake code. If you need it urgently then I could just copy it over to OR for now.

donn commented 3 months ago

Not urgent! I already have a dirty patch I can apply during the build process, so take all the time you need to do it right.