title: Undefined symbols for architecture x86_64 during linking
body: <p>I am compiling a pretty large C and C++ program called APBS using Apple clang version 12.0.5.  When make gets to a linker step to link the headers with the main source <code>routines.c</code> it gives this error below.  it has to be something easy</p>
  <pre><code>[ 30%] Linking C shared library ../lib/libapbs_routines.dylib
  + cd /Users/brian/tools/apbs/build/src
  + /usr/local/Cellar/cmake/3.22.1/bin/cmake -E cmake_link_script CMakeFiles/apbs_routines.dir/link.txt --verbose=
  Undefined symbols for architecture x86_64:
    &quot;_Vacc_atomSASA&quot;, referenced from:
        _initAPOL in routines.c.o
    &quot;_Vacc_atomSurf&quot;, referenced from:
        _forceAPOL in routines.c.o
    &quot;_Vacc_atomdSASA&quot;, referenced from:
        _forceAPOL in routines.c.o
    &quot;_Vacc_atomdSAV&quot;, referenced from:
        _forceAPOL in routines.c.o
    &quot;_Vacc_ctor&quot;, referenced from:
        _initAPOL in routines.c.o
    &quot;_Vacc_dtor&quot;, referenced from:
        _initAPOL in routines.c.o
    &quot;_Vacc_totalSASA&quot;, referenced from:
        _initAPOL in routines.c.o
  ...
   &quot;_Vgrid_ctor&quot;, referenced from:
        _loadDielMaps in routines.c.o
        _loadKappaMaps in routines.c.o
        _loadPotMaps in routines.c.o
        _loadChargeMaps in routines.c.o
        _writedataMG in routines.c.o
    &quot;_Vgrid_dtor&quot;, referenced from:
        _killDielMaps in routines.c.o
        _killKappaMaps in routines.c.o
        _killPotMaps in routines.c.o
        _killChargeMaps in routines.c.o
        _writedataMG in routines.c.o
    &quot;_Vgrid_readDX&quot;, referenced from:
        _loadDielMaps in routines.c.o
        _loadKappaMaps in routines.c.o
        _loadPotMaps in routines.c.o
        _loadChargeMaps in routines.c.o
  ...
  ld: symbol(s) not found for architecture x86_64
  clang: error: linker command failed with exit code 1 (use -v to see invocation)
  </code></pre>
  <p>here is the tree for the src but they are not getting built in the build/src where the headers that define these functions are in src/fem, src/generic</p>
  <pre><code>/Users/brian/tools/apbs/src
  ├── CMakeLists.txt
  ├── apbs.h
  ├── fem
  │   ├── CMakeLists.txt
  │   ├── vcsm.c
  │   ├── vcsm.h
  │   ├── vfetk.c
  │   ├── vfetk.h
  │   ├── vpee.c
  │   └── vpee.h
  ├── generic
  │   ├── CMakeLists.txt
  │   ├── apolparm.c
  │   ├── apolparm.h
  │   ├── bemparm.c
  │   ├── bemparm.h
  │   ├── femparm.c
  │   ├── femparm.h
  │   ├── geoflowparm.c
  │   ├── geoflowparm.h
  │   ├── mgparm.c
  │   ├── mgparm.h
  │   ├── nosh.c
  │   ├── nosh.h
  │   ├── pbamparm.c
  │   ├── pbamparm.h
  │   ├── pbeparm.c
  │   ├── pbeparm.h
  │   ├── pbsamparm.c
  │   ├── pbsamparm.h
  │   ├── vacc.c
  │   ├── vacc.h
  │   ├── valist.c
  │   ├── valist.h
  │   ├── vatom.c
  │   ├── vatom.h
  │   ├── vcap.c
  │   ├── vcap.h
  │   ├── vclist.c
  │   ├── vclist.h
  │   ├── vgreen.c
  │   ├── vgreen.h
  │   ├── vhal.h
  │   ├── vmatrix.h
  │   ├── vparam.c
  │   ├── vparam.h
  │   ├── vpbe.c
  │   ├── vpbe.h
  │   ├── vstring.c
  │   ├── vstring.h
  │   └── vunit.h
  ├── main.c
  ├── mg
  │   ├── CMakeLists.txt
  │   ├── vgrid.c
  │   ├── vgrid.h
  │   ├── vmgrid.c
  │   ├── vmgrid.h
  │   ├── vopot.c
  │   ├── vopot.h
  │   ├── vpmg.c
  │   ├── vpmg.h
  │   ├── vpmgp.c
  │   └── vpmgp.h
  ├── pmgc
  │   ├── CMakeLists.txt
  │   ├── PMG-README.txt
  │   ├── README.txt
  │   ├── buildAd.c
  │   ├── buildAd.h
  │   ├── buildBd.c
  │   ├── buildBd.h
  │   ├── buildGd.c
  │   ├── buildGd.h
  │   ├── buildPd.c
  │   ├── buildPd.h
  │   ├── cgd.c
  │   ├── cgd.h
  │   ├── gsd.c
  │   ├── gsd.h
  │   ├── matvecd.c
  │   ├── matvecd.h
  │   ├── mgcsd.c
  │   ├── mgcsd.h
  │   ├── mgdrvd.c
  │   ├── mgdrvd.h
  │   ├── mgfasd.c
  │   ├── mgfasd.h
  │   ├── mgsubd.c
  │   ├── mgsubd.h
  │   ├── mikpckd.c
  │   ├── mikpckd.h
  │   ├── mlinpckd.c
  │   ├── mlinpckd.h
  │   ├── mypdec.c
  │   ├── mypdec.h
  │   ├── newdrvd.c
  │   ├── newdrvd.h
  │   ├── newtond.c
  │   ├── newtond.h
  │   ├── powerd.c
  │   ├── powerd.h
  │   ├── smoothd.c
  │   └── smoothd.h
  ├── routines.c
  └── routines.h
  </code></pre>
  <p>and the src/CMakeLists.txt adds these directories, seems super simple to solve but I am just learning</p>
  <pre><code>cmake_minimum_required(VERSION 3.8)
  
  macro(add_items TYPE)
  
      # Make sure the TYPE argument is valid
      set(ALLOWABLE_TYPES SOURCES EXTERNAL_HEADERS INTERNAL_HEADERS)
      list(FIND ALLOWABLE_TYPES ${TYPE} VALID_TYPE)
      if(VALID_TYPE EQUAL -1)
          message(
              FATAL_ERROR
              &quot;Passed an invalid type to add_items macro.  &quot;
              &quot;Must be one of SOURCES, EXTERNAL_HEADERS, or INTERNAL_HEADERS.  &quot;
              &quot;Was ${TYPE}&quot;
          )
      endif()
  
      # The items to add will be any additional parameters beyond TYPE
      set(ITEMS ${ARGN})
  
      # Add each item successively to the appropriately typed list
      foreach(ITEM ${ITEMS})
          list(APPEND ${TYPE} &quot;${ITEM}&quot;)
      endforeach()
  
  endmacro()
  
  macro(add_sublibrary LIBRARY)
      set(LIBRARY_NAME &quot;apbs_${LIBRARY}&quot;)
      set(LIBRARY_DEPENDENCIES ${APBS_LIBS} ${ARGN})
      message(STATUS &quot;Adding ${LIBRARY_NAME}&quot;)
      message(STATUS &quot;With source files ${SOURCES}&quot;)
      message(STATUS &quot;With external header files ${EXTERNAL_HEADERS}&quot;)
      message(STATUS &quot;With internal header files ${INTERNAL_HEADERS}&quot;)
      message(STATUS &quot;With library dependencies ${LIBRARY_DEPENDENCIES}&quot;)
      add_library(${LIBRARY_NAME} ${SOURCES} ${EXTERNAL_HEADERS} ${INTERNAL_HEADERS})
      target_link_libraries(${LIBRARY_NAME} ${LIBRARY_DEPENDENCIES})
      #add_dependencies(${LIBRARY_NAME} ${LIBRARY_DEPENDENCIES})
      INSTALL(FILES ${EXTERNAL_HEADERS} DESTINATION ${HEADER_INSTALL_PATH}/${LIBRARY})
      INSTALL(TARGETS ${LIBRARY_NAME} DESTINATION ${LIBRARY_INSTALL_PATH})
      list(APPEND APBS_INTERNAL_LIBS ${LIBRARY_NAME})
      set(APBS_INTERNAL_LIBS ${APBS_INTERNAL_LIBS} PARENT_SCOPE)
      message(STATUS &quot;Added ${LIBRARY_NAME}&quot;)
  endmacro()
  
  add_subdirectory(generic)
  add_subdirectory(pmgc)
  add_subdirectory(mg)
  
  if(ENABLE_FETK)
     add_subdirectory(fem)
  endif(ENABLE_FETK)
  
  add_items(SOURCES routines.c)
  add_sublibrary(routines)
  
  message(STATUS &quot;External Headers: ${EXTERNAL_HEADERS}&quot;)
  
  #add_executable(apbs main.c routines.c)
  add_executable(apbs main.c apbs.h routines.c routines.h)
  message(STATUS &quot; &quot;)
  message(STATUS &quot;APBS Libraries: ${APBS_LIBS}&quot;)
  message(STATUS &quot;Internal Libraries: ${APBS_INTERNAL_LIBS}&quot;)
  message(STATUS &quot; &quot;)
  
  #add_dependencies(apbs ${BEM_LIB})
  #target_include_directories(apbs PRIVATE apbs.h routines.h)
  target_link_libraries(apbs ${APBS_LIBS} ${APBS_INTERNAL_LIBS} ${APBS_LIBS})
  #add_dependencies(apbs ${APBS_LIBS} ${APBS_INTERNAL_LIBS} ${APBS_LIBS})
  
  #configure_file(
  #    ${APBS_ROOT}/src/.config/apbscfg.h.in
  #    ${APBS_BUILD}/src/apbscfg.h
  #    )
  
  if(ENABLE_iAPBS)
  #    ADD_LIBRARY(apbs_routines routines.c routines.h)
  #    INSTALL(TARGETS apbs_routines DESTINATION ${LIBRARY_INSTALL_PATH})
      INSTALL(FILES ${APBS_BUILD}/src/apbscfg.h DESTINATION ${HEADER_INSTALL_PATH})
  endif()
  
  
  ################################################################################
  #  We have to fix the dynamically linked libraries 
  ################################################################################
  if(APPLE)
    set(HARDPATH &quot;${PROJECT_BINARY_DIR}/fetk/lib&quot;)
    foreach (hardlib ${APBS_LIBS})
      set(HARDNAME &quot;lib${hardlib}.1.dylib&quot;)
      message(STATUS &quot;#############################################################&quot;)
      message(STATUS &quot;#############################################################&quot;)
      message(STATUS &quot;#############################################################&quot;)
      message(STATUS &quot;#############################################################&quot;)
      message(STATUS &quot;** Change path for hardlib - ${hardlib}&quot;)
      message(STATUS &quot;COMMAND install_name_tool -change ${HARDPATH}/${HARDNAME} @executable_path/../lib/${HARDNAME} ${PROJECT_BINARY_DIR}/bin/apbs&quot;)
      message(STATUS &quot;#############################################################&quot;)
      add_custom_command(TARGET apbs POST_BUILD
                         COMMAND install_name_tool -change ${HARDPATH}/${HARDNAME} @executable_path/../lib/${HARDNAME} ${PROJECT_BINARY_DIR}/bin/apbs
      )
    endforeach()
  endif()
  
  INSTALL(FILES apbs.h routines.h DESTINATION ${HEADER_INSTALL_PATH})
  INSTALL(TARGETS apbs DESTINATION ${EXECUTABLE_INSTALL_PATH})
  </code></pre>
  <p>Sorry also here is the <code>CMakeFiles/apbs_routines.dir/link.txt</code></p>
  <pre><code>/usr/bin/gcc  -fPIC -O2 -g -DNDEBUG -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk -dynamiclib -Wl,-headerpad_max_install_names -o ../lib/libapbs_routines.dylib -install_name @rpath/libapbs_routines.dylib CMakeFiles/apbs_routines.dir/routines.c.o   -L/Users/brian/tools/apbs/build/fetk/lib  -L/Users/brian/tools/apbs/build/geoflow-prefix/src/geoflow-build/lib  -Wl,-rpath,/Users/brian/tools/apbs/build/fetk/lib -Wl,-rpath,/Users/brian/tools/apbs/build/geoflow-prefix/src/geoflow-build/lib -lm -lstdc++ -lmaloc -lamd -lpunc -lmc -lgamer -lsuperlu -lumfpack -lblas -lvf2c -ltetgen -ltriangle -lreadline -ltermcap /usr/local/lib/libumfpack.dylib /usr/local/Cellar/openblas/0.3.19/lib/libopenblas.dylib /usr/local/Cellar/superlu/5.2.2_1/lib/libsuperlu.dylib -lGeometricFlowLib -Xclang -fopenmp
  </code></pre>