I am trying to build the library https://github.com/sdwfrost/liblsoda
using CMake. Specifically, the directory structure is the following:
.
├── CMakeLists.txt
├── main.cpp
└── src
├── blas.h
├── cfode.c
├── cfode_static.c
├── cfode_static.inc
├── CMakeLists.txt
├── common.c
├── common.h
├── corfailure.c
├── correction.c
├── daxpy.c
├── ddot.c
├── dgefa.c
├── dgesl.c
├── dscal.c
├── ewset.c
├── fnorm.c
├── idamax.c
├── intdy.c
├── lsoda.c
├── lsoda.h
├── lsoda_internal.h
├── Makefile
├── methodswitch.c
├── orderswitch.c
├── printcf.c
├── prja.c
├── scaleh.c
├── solsy.c
├── stoda.c
├── strdup_printf.c
└── vmnorm.c
and the contents of the CMakeLists.txt in the src directory is:
set(TARGET lsodaC)
set(SRC
${CMAKE_CURRENT_SOURCE_DIR}/cfode.c
${CMAKE_CURRENT_SOURCE_DIR}/cfode_static.c
${CMAKE_CURRENT_SOURCE_DIR}/common.c
${CMAKE_CURRENT_SOURCE_DIR}/corfailure.c
${CMAKE_CURRENT_SOURCE_DIR}/correction.c
${CMAKE_CURRENT_SOURCE_DIR}/daxpy.c
${CMAKE_CURRENT_SOURCE_DIR}/ddot.c
${CMAKE_CURRENT_SOURCE_DIR}/dgefa.c
${CMAKE_CURRENT_SOURCE_DIR}/dgesl.c
${CMAKE_CURRENT_SOURCE_DIR}/dscal.c
${CMAKE_CURRENT_SOURCE_DIR}/fnorm.c
${CMAKE_CURRENT_SOURCE_DIR}/idamax.c
${CMAKE_CURRENT_SOURCE_DIR}/intdy.c
${CMAKE_CURRENT_SOURCE_DIR}/lsoda.c
${CMAKE_CURRENT_SOURCE_DIR}/methodswitch.c
${CMAKE_CURRENT_SOURCE_DIR}/orderswitch.c
${CMAKE_CURRENT_SOURCE_DIR}/prja.c
${CMAKE_CURRENT_SOURCE_DIR}/scaleh.c
${CMAKE_CURRENT_SOURCE_DIR}/solsy.c
${CMAKE_CURRENT_SOURCE_DIR}/stoda.c
${CMAKE_CURRENT_SOURCE_DIR}/vmnorm.c
${CMAKE_CURRENT_SOURCE_DIR}/strdup_printf.c
)
add_library(${TARGET} SHARED ${SRC})
set_target_properties(${TARGET} PROPERTIES LINKER_LANGUAGE CXX)
# SET(CMAKE_C_LINK_EXECUTABLE ${CMAKE_CXX_LINK_EXECUTABLE})
set_property(TARGET ${TARGET} PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(${TARGET}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)
target_link_directories(${TARGET}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)
Furthermore, the main.cpp is the following (taken from the test directory of the above repo):
/**
*
*/
#include <iostream>
#include "common.h"
#include "lsoda.h"
int fex(double t, double *y, double *ydot, void *data)
{
ydot[0] = 1.0E4 * y[1] * y[2] - .04E0 * y[0];
ydot[2] = 3.0E7 * y[1] * y[1];
ydot[1] = -1.0 * (ydot[0] + ydot[2]);
return(0);
}
int test(void)
{
double atol[3], rtol[3], t, tout, y[3];
int neq = 3;
int iout;
y[0] = 1.0E0;
y[1] = 0.0E0;
y[2] = 0.0E0;
t = 0.0E0;
tout = 0.4E0;
struct lsoda_opt_t opt = {0};
opt.ixpr = 0;
opt.rtol = rtol;
opt.atol = atol;
opt.itask = 1;
rtol[0] = rtol[2] = 1.0E-4;
rtol[1] = 1.0E-4;
atol[0] = 1.0E-6;
atol[1] = 1.0E-10;
atol[2] = 1.0E-6;
struct lsoda_context_t ctx;
ctx.function = fex;
ctx.neq = neq;
ctx.data = nullptr;
ctx.state = 1;
lsoda_prepare(&ctx, &opt);
for (iout = 1; iout <= 12; iout++) {
lsoda(&ctx, y, &t, tout);
printf(" at t= %12.4e y= %14.6e %14.6e %14.6e\n", t, y[0], y[1], y[2]);
if (ctx.state <= 0) {
printf("error istate = %d\n", ctx.state);
exit(0);
}
tout = tout * 10.0E0;
}
lsoda_free(&ctx);
return(0);
}
int main(int argc, char **argv) {
test();
return 0;
}
Finally, the root-most CMakeLists.txt has the following contents:
cmake_minimum_required(VERSION 3.14)
project(sample_mwe)
set(CMAKE_CXX_FLAGS "-O3")
add_executable(main main.cpp)
add_subdirectory(src)
target_link_libraries(main
PUBLIC lsodaC
)
The question is, when executing
mkdir build
cd build
cmake ..
make main
I am getting
[ 4%] Building C object src/CMakeFiles/lsodaC.dir/cfode.c.o
[ 8%] Building C object src/CMakeFiles/lsodaC.dir/cfode_static.c.o
[ 12%] Building C object src/CMakeFiles/lsodaC.dir/common.c.o
[ 16%] Building C object src/CMakeFiles/lsodaC.dir/corfailure.c.o
[ 20%] Building C object src/CMakeFiles/lsodaC.dir/correction.c.o
[ 24%] Building C object src/CMakeFiles/lsodaC.dir/daxpy.c.o
[ 28%] Building C object src/CMakeFiles/lsodaC.dir/ddot.c.o
[ 32%] Building C object src/CMakeFiles/lsodaC.dir/dgefa.c.o
[ 36%] Building C object src/CMakeFiles/lsodaC.dir/dgesl.c.o
[ 40%] Building C object src/CMakeFiles/lsodaC.dir/dscal.c.o
[ 44%] Building C object src/CMakeFiles/lsodaC.dir/fnorm.c.o
[ 48%] Building C object src/CMakeFiles/lsodaC.dir/idamax.c.o
[ 52%] Building C object src/CMakeFiles/lsodaC.dir/intdy.c.o
[ 56%] Building C object src/CMakeFiles/lsodaC.dir/lsoda.c.o
[ 60%] Building C object src/CMakeFiles/lsodaC.dir/methodswitch.c.o
[ 64%] Building C object src/CMakeFiles/lsodaC.dir/orderswitch.c.o
[ 68%] Building C object src/CMakeFiles/lsodaC.dir/prja.c.o
[ 72%] Building C object src/CMakeFiles/lsodaC.dir/scaleh.c.o
[ 76%] Building C object src/CMakeFiles/lsodaC.dir/solsy.c.o
[ 80%] Building C object src/CMakeFiles/lsodaC.dir/stoda.c.o
[ 84%] Building C object src/CMakeFiles/lsodaC.dir/vmnorm.c.o
[ 88%] Building C object src/CMakeFiles/lsodaC.dir/strdup_printf.c.o
[ 92%] Linking CXX shared library liblsodaC.so
[ 92%] Built target lsodaC
[ 96%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[100%] Linking CXX executable main
/usr/bin/ld: CMakeFiles/main.dir/main.cpp.o: in function `test()':
main.cpp:(.text+0x185): undefined reference to `lsoda_prepare(lsoda_context_t*, lsoda_opt_t*)'
/usr/bin/ld: main.cpp:(.text+0x1ac): undefined reference to `lsoda(lsoda_context_t*, double*, double*, double)'
/usr/bin/ld: main.cpp:(.text+0x1fd): undefined reference to `lsoda_free(lsoda_context_t*)'
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/main.dir/build.make:98: main] Error 1
make[2]: *** [CMakeFiles/Makefile2:100: CMakeFiles/main.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:107: CMakeFiles/main.dir/rule] Error 2
make: *** [Makefile:124: main] Error 2
The question is why. I am building the C-portion src as a library, right, why won't it work the "usual" way?