cmake build linking error with source tree layout

92 views
Skip to first unread message

timo Hyvärinen

unread,
Dec 28, 2023, 8:49:09 AM12/28/23
to dea...@googlegroups.com, samuel.the...@gmail.com
Dear deal.ii developers and user community,

Happy New Year! 🎊

I'm trying to split source code into different directories following to this documentation

Unfortunately, I keep getting the following error in linking step between libmylib.a and main:
"/projappl/project_xxxx/PDE/main.cc:115:undefined reference to `MyNamespace_mpi::pde_solver<3>::pde_solver(unsigned int)
 /projappl/project_xxxx/PDE/main.cc:116: undefined reference to `MyNamespace_mpi::pde_solver<3>::run()'
 collect2: error: ld returned 1 exit status
'"
I didn't get this error when all members and class declarations are located in one source *cc file.

My source layout is 
PDE
  |--main.cc
  |--CMakeLists.txt
  |--mylib
        |--CMakeLists.txt
        |--header1.h
        |--header2.h
        |--source.cc
, where header1.h declares MyNamespace_mpi and pde_solver<>, with source.cc implementing all members in pde_solver<>.
And header2.h defines dirichlet boundary condition functions in namespace  MyNamespace_mpi.

Following documentation, I wrote PDE/CMakeLists.txt as 
"
cmake_minimum_required(VERSION 3.13.4)

find_package(deal.II 9.3.3 REQUIRED
  HINTS ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR}
  )
deal_ii_initialize_cached_variables()
project(cmaketest)

include_directories(mylib)
link_directories(mylib)

add_subdirectory(mylib)

add_executable(mycode main.cc)
deal_ii_setup_target(mycode)
target_link_libraries(mycode mylib)
"
and PDE/mylib/CMakeLists.txt as
"
add_library(mylib
  source.cc
  header1.h
  header2.h
  )
deal_ii_setup_target(mylib)
I need source directory layout because I have many new functions that must be added into pde_solver<>. 
It seems it is a linking problem. I'm not sure if it is related to the pre-built deal.ii library. 
I hope developers and deal.ii's users can give me suggestions to solve this issue.

Best,
Tim


Wolfgang Bangerth

unread,
Dec 28, 2023, 10:58:02 AM12/28/23
to dea...@googlegroups.com
On 12/28/23 06:48, timo Hyvärinen wrote:
>
> Unfortunately, I keep getting the following error in linking step between
> libmylib.a and main:
> "/projappl/project_xxxx/PDE/main.cc:115:undefined reference to
> `MyNamespace_mpi::pde_solver<3>::pde_solver(unsigned int)
>  /projappl/project_xxxx/PDE/main.cc:116: undefined reference to
> `MyNamespace_mpi::pde_solver<3>::run()'

Timo:
You need what is called an 'explicit instantiation'. If you search the
archives of this mailing list, you will find the issue discussed in more detail.

Best
W.

--
------------------------------------------------------------------------
Wolfgang Bangerth email: bang...@colostate.edu
www: http://www.math.colostate.edu/~bangerth/


Tim hyvärinen

unread,
Dec 28, 2023, 6:18:09 PM12/28/23
to deal.II User Group
hi, Wolfgang

Thank you for the tips, error gone.

In case anyone would search for solution for multiple sources layout link error in future, I would remark it a little bit:

This error is caused by a feature called instantiation controlling after c++11, see section 16.1.5 of C++ Primer (C++11 S.B.Lippman etc)
What it does is guarantee there is only one template instantiation definition over the whole source tree and their corresponding object files.
and section 16.1.5 of C++ Primer, C++ 11 (and newer) achieves this by explicit instantiation definition of template in library source code.  

In my case, main.cc only knows the declaration by including header, but can't directly see mylib, where the pde_solver<> is defined. This results in main.cc.o doesn't have class instantiation.
Then I must add the unique definition of class instantiation i.e., template class pde_solver<3> into last line of mylib/source.cc.

best,
Timo
Reply all
Reply to author
Forward
0 new messages