Closed smith-nekrald closed 3 weeks ago
Take a look at the discussion https://github.com/coin-or/CppAD/discussions/175
In particular the suggestion 'From the description above it does not seem like you are including cppad_lib in the linking.'
But how exactly to include that particular library? Please see below my CMakeLists.txt. There is an entry called cppad_lib, but the problem remains.
cmake_minimum_required(VERSION 3.5.1
FATAL_ERROR)
# It's actually not a true cmake way of making such things, but here its more comfortable :)
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_RELEASE "")
add_compile_options(
-Wall
-std=c++20
-pthread
-DHAVE_CSTDDEF
)
include_directories(
"/usr/local/include/coin-or",
"/usr/include/coin",
)
link_directories(
)
set(SEA_LIBRARIES
"-lOsiCbc -lCbc -lCgl -lOsiClp -lOsi -lClp -lCoinUtils -lm -lz"
"-lbz2 -llapack -lblas -ldl -lgflags -lipopt -pthread -lunwind -lwsmp64"
"-luuid -llog4cpp -ljsoncpp -lstdc++fs -lcppad_lib"
)
file(GLOB_RECURSE SOURCES "src/*.cpp")
add_executable(sea ${SOURCES})
target_compile_options(sea PUBLIC -O3 -march=native -fopenmp)
target_link_libraries(sea
${SEA_LIBRARIES}
"cppad_lib"
"cppad_ipopt"
)
And this is how compiler error log sounds:
[ 2%] Linking CXX executable sea
/usr/bin/ld: CMakeFiles/sea.dir/src/backend/ipopt/recalculate.cpp.o: in function `void CppAD::put_check_for_nan<double>(CppAD::vector<double> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std:
:allocator<char> >&) [clone .isra.0]':
recalculate.cpp:(.text+0x8d8e): undefined reference to `CppAD::local::temp_file[abi:cxx11]()'
/usr/bin/ld: CMakeFiles/sea.dir/src/backend/lagrangian_relaxation/gm_sea/gm_src/ufgm_optimizer.cpp.o: in function `void CppAD::put_check_for_nan<double>(CppAD::vector<double> const&, std::__cxx11::basic_string<c
har, std::char_traits<char>, std::allocator<char> >&) [clone .isra.0]':
ufgm_optimizer.cpp:(.text+0x6fde): undefined reference to `CppAD::local::temp_file[abi:cxx11]()'
/usr/bin/ld: CMakeFiles/sea.dir/src/backend/lagrangian_relaxation/gm_sea/sea_gm_apply.cpp.o: in function `void CppAD::put_check_for_nan<double>(CppAD::vector<double> const&, std::__cxx11::basic_string<char, std:
:char_traits<char>, std::allocator<char> >&) [clone .isra.0]':
sea_gm_apply.cpp:(.text+0x5b2e): undefined reference to `CppAD::local::temp_file[abi:cxx11]()'
/usr/bin/ld: CMakeFiles/sea.dir/src/backend/lagrangian_relaxation/gm_sea/sea_gm_apply.cpp.o: in function `void CppAD::put_check_for_nan<CppAD::AD<double> >(CppAD::vector<CppAD::AD<double> > const&, std::__cxx11:
:basic_string<char, std::char_traits<char>, std::allocator<char> >&) [clone .isra.0]':
sea_gm_apply.cpp:(.text+0x5f0e): undefined reference to `CppAD::local::temp_file[abi:cxx11]()'
/usr/bin/ld: CMakeFiles/sea.dir/src/backend/lagrangian_relaxation/lr_cppad.cpp.o: in function `void CppAD::put_check_for_nan<double>(CppAD::vector<double> const&, std::__cxx11::basic_string<char, std::char_trait
s<char>, std::allocator<char> >&) [clone .isra.0]':
lr_cppad.cpp:(.text+0x257e): undefined reference to `CppAD::local::temp_file[abi:cxx11]()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/sea.dir/build.make:849: sea] Error 1
make[1]: *** [CMakeFiles/Makefile2:84: CMakeFiles/sea.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
The only workaround I have found so far is to include the following header (copied from inside CppAD):
#pragma once
# include <vector>
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <cppad/configure.hpp>
# include <cppad/local/temp_file.hpp>
# include <filesystem>
# define DIR_SEP '/'
namespace CppAD {
namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
std::string temp_file(void)
{ // path
using std::filesystem::path;
//
// tmp_dir_path
path tmp_dir_path = std::filesystem::temp_directory_path();
//
// tmp_dir_str
std::string tmp_dir_str = tmp_dir_path.string();
if( tmp_dir_str.back() != DIR_SEP )
tmp_dir_str += DIR_SEP;
//
// pattern_str
std::string pattern_str = tmp_dir_str;
pattern_str += "fileXXXXXX";
//
// pattern_vec
std::vector<char> pattern_vec( pattern_str.size() + 1 );
for(size_t i = 0; i < pattern_str.size(); ++i)
pattern_vec[i] = pattern_str[i];
pattern_vec[ pattern_str.size() ] = '\0';
//
// fd, pattrern_vec
int fd = mkstemp( pattern_vec.data() );
if( fd < 0 )
return "";
close(fd);
//
// file_name
std::string file_name = pattern_vec.data();
return file_name;
}
}
}
Please take a look at the following https://github.com/coin-or/CppAD/discussions/175
Many other people are having this problem and I think I should put something in the documentation for this: https://cppad.readthedocs.io/en/latest/
Do you have a suggesiton ? Where did you look in the documentation ? Did you do a search for link error
or temp_file
?
Did the message above solve the problem for you ? If so, would you please close this issue.
No, the message above did not help. Sounds like the library does not have temp_file method inside for some reason. The problem was solved the other way: by directly compiling with adding the temp_file method to the header included in the entry point main.cpp.
temp_file should be in cppad_lib. What system / compiler are you using and what does your link command look like ?
Is this still a problem for you ?
Had the same issue. The workaround from @smith-nekrald as described above worked for me.
@smith-nekrald and @Geryyy what do you get in response to the command ?
pkg-config cppad --libs
@bradbell $ pkg-config cppad --libs -L/usr/local/lib -lcppad_lib -lcppad_ipopt -lipopt
@Geryyy What happens when you add these flags to you link command (without the separate copy of temp_file mentioned above) ?
If you are using cmake to link your program, see the following: https://cmake.org/cmake/help/latest/module/FindPkgConfig.html#command:pkg_check_modules
Thank you for the hint!
Adding this to CMakeLists.txt fixed it for me:
find_package(PkgConfig REQUIRED)
pkg_check_modules(CPPAD REQUIRED cppad)
and
target_link_libraries(${PROJECTNAME} ... ${CPPAD_LIBRARIES})
In CMakeCache.txt the lib paths are:
//Path to a library.
pkgcfg_lib_CPPAD_cppad_ipopt:FILEPATH=/usr/local/lib/libcppad_ipopt.a
//Path to a library.
pkgcfg_lib_CPPAD_cppad_lib:FILEPATH=/usr/local/lib/libcppad_lib.so
//Path to a library.
pkgcfg_lib_CPPAD_ipopt:FILEPATH=/usr/local/lib/libipopt.so
@Geryyy Does this mean that this problem is solved for you ?
If so, I am going to close this issue and convert it to a discussion.
Yes, it is solved for me. Thank you!
After compiling and installing CppAD, there was a problem to link CppAD and Ipopt with C++ linker. Looks like the method std::string temp_file(void); in namespace CppAD::local is referenced withing CppAD include and is not present in the linking library. So far I have just grepped and copied this method to a separate header (and therefore linked), but I guess this is considered an issue.