Compiling Bzip2 with C++11 - c++11

I'm trying to compile the MultiBoost Library with C++11 but I can't make it work. The problem seems to be with the BZip2 Library that is used internally. More specificly there is a wrapper called Bzip2Wrapper to provide a c++ interface to the C library. All the files of the C library are included in the same folder. When using the default make file everything works but when I change
project(multiboost)
to
project(multiboost CXX)
I get the following errors:
libMultiBoostLib.a(Serialization.cpp.o): In function `Bzip2WrapperReader::open(char const*)':
Serialization.cpp:(.text._ZN18Bzip2WrapperReader4openEPKc[_ZN18Bzip2WrapperReader4openEPKc]+0x97): undefined reference to `BZ2_bzReadOpen'
Serialization.cpp:(.text._ZN18Bzip2WrapperReader4openEPKc[_ZN18Bzip2WrapperReader4openEPKc]+0xc5): undefined reference to `BZ2_bzReadClose'
libMultiBoostLib.a(Serialization.cpp.o): In function `Bzip2WrapperReader::close()': ...
The CMakeList file looks like this
# Bzip2
file(GLOB bzip2_SRCS "${BASEPATH}/Bzip2/*.cpp" "${BASEPATH}/Bzip2/*.c" "${BASEPATH}/Bzip2/*.h")
add_library(Bzip2Lib STATIC ${bzip2_SRCS})
#add_library(bzip2 SHARED ${bzip2_lib_SRCS})
...
# adding library to the exec
target_link_libraries(multiboost MultiBoostLib Bzip2Lib)
Any ideas what could go wrong? I don't even know what the problem is.
Thanks!

This does not look like a C++11 error but an error in the Build system.
I have not looked at the Code, but from the output you added something like this
target_link_libraries(MultiBoostLib PUBLIC Bzip2Lib)
should add the missing dependency from libMultiBoostLib on libBzip2Lib.

I found the problem. I was adding "CXX" to my project description which disabled the use of C. Therefore the libraries (in C) could not be compiled. Changing it to "project(name C CXX)" solved this issue. I then also needed to include the line "set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")" to enable C++11 support. Now everything is working.
Thanks a lot!

Related

Link a static library to object in cmake

I am trying to compile a project using cmake. I need to use an external static library in src1.c so I utilized target_link_libraries to link it to the object file. However, I am getting some complains about missing functions in src1.c which should be in the external library.
add_library(input_output OBJECT
src/src1.c
src/src2.c
src/src3.c)
find_library(EXTERNAL_LIB NAMES libexternallib.a PATHS ~/lib)
target_link_libraries(input_output PRIVATE
"${EXTERNAL_LIB}")
So I am not sure what I should do at this point. the logic sounds right at least
UPDATE1: I also added the external library directly into the linker command
add_compile_options(-Wall -Wextra --std=c99 -L~/lib -lexternallib)
add_link_options(-L~/lib -lexternallib)
but this added the library flags before the object file for the linker command, which leads to some other problem with ordering the linker arguments
It's hard to say what is really the reason for your error here, but I'll give it a try.
First of all, you don't need to link manually with add_compile_options or add_link_options. The cmake command target_link_libraries is doing that for you.
What I could imagine, because of the missing functions, that you need to add a header include directory from the dependency.
e.g.:
target_include_directories(input_output PRIVATE /path/to/external_library_header)

How to add compile flags in cmake on windows?

I wrote a project using CMake (with ninja and Visual Studio 2017 C++ compiler), with two modules lib_A and lib_B
lib_B depends one lib_A.
Both lib_B and lib_A define std::vector < size_t >.
Finally, the compiler told me: LNK2005 lib_A: std::vector < size_t > already defined in lib_B
I searched answers, and they gave the solution to add link flag /FORCE:MULTIPLE, page1 and page2.
I tried all these, but none of them work.
Use target_link_libraries
with target_link_libraries(lib_B lib_A INTERFACE "/FORCE:MULTIPLE")
compiler tells me The INTERFACE, PUBLIC or PRIVATE option must appear as the second argument, just after the target name.
with target_link_libraries(lib_B INTERFACE "/FORCE:MULTIPLE" lib_A )
compiler tells me ninja: error: '/FORCE:MULTIPLE', needed by 'lib_B', missing and no known rule to make it
Use CMAKE_EXE_LINKER_FLAGS
withset(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "/FORCE:MULTIPLE")
compile tells me LINK : warning LNK4012: value “x64;/FORCE:MULTIPLE” is invalid, must be one of "ARM, EBC, HYBRID_X86_ARM64X64, or X86" omit this option"
Use set_target_properties
with CMake code
get_target_property(TEMP lib_B COMPILE_FLAGS)
if(TEMP STREQUAL "TEMP-NOTFOUND")
SET(TEMP "") # Set to empty string
else()
SET(TEMP "${TEMP} ") # A space to cleanly separate from existing content
endif()
# Append our values
SET(TEMP "${TEMP} /FORCE:MULTIPLE" )
set_target_properties(lib_B PROPERTIES COMPILE_FLAGS ${TEMP} )
The compiler tells me cl: command line error D8021 : invalid parameter "/FORCE:MULTIPLE"
If I change /FORCE:MULTIPLE to -Wl,--allow-multiple-definition, compiler tells me similar result.
Could anyone help me?
Does add link flag with any error?
You can use target_link_options in CMake ≥ 3.13 or set_target_properties with the LINK_FLAGS property before.
i.e. target_link_options(${PROJECT_NAME} PUBLIC $<$<CXX_COMPILER_ID:MSVC>:/FORCE:MULTIPLE>)
This also uses generator expressions to only apply the flag for MSVC.
But it seems like both your libraries are shared (DLL), but you are statically linking the runtime to both.
I don’t think that that’s a good idea.
Try either linking to the runtime dynamically for both libs if you want to dynamically link to them, or use the static runtime but build both libraries as static library too.
Adding the following line worked for me:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /FORCE:MULTIPLE")

Why am I getting duplicate symbol linker errors when building in CMake on Windows?

I have a CMake setup to link together 4 static libraries and 1 shared one into a top level shared library (Let's call it Top.dll). This will work fine except for one thing. I have a module definition file that expresses which symbols should be public. Top.dll builds and so far so good.
Now when I try to link an executable with Top.dll via CMake I get linker errors for every public symbol claiming it is defined in two places (Top.dll and the static library in which it was actually defined) even though Top.dll contains no original definitions of its own. If I remove the static library then as expected I get unresolved symbol errors. If I remove the module definition file, I get the same. It seems like it is either there zero times or twice. Is there some setting I am missing here? I don't think I'm using CMake in a non-basic way...
UPDATE An explanation via CMake
# setup the lib
add_subdirectory(vendor/A) #shared library
add_subdirectory(vendor/B) #static library
add_subdirectory(vendor/C) #static library
add_library(Top SHARED ${ALL_SRC_FILES})
target_link_libraries(Top A B C)
set_target_properties(Top PROPERTIES LINK_FLAGS
"/def:${PROJECT_SOURCE_DIR}/definitions.def") #contains symbols from B
add_subdirectory(C/Tests)
# CMakeLists.txt from C/Tests
add_executable(Tests ${SRC_FILES})
target_link_libraries(Tests Top)
The above is simplified, but I will get errors like the following at the point that the C/tests project is compiled:
B.lib(xxx.obj) : error LNK2005: _ABC already defined in Top.lib(Top.dll)
If I remove B.lib from the target_link_libraries call, then as expected I get unresolved symbols. If I remove the /def line, same result.
I've been able to get around this by setting the target_link_libraries of B and C to private. This may or may not be the correct solution and I will wait for other answers. If I don't do this it appears that the dependency is carried up to the final executable (So it links to both Top.dll and B.lib, etc).

Add dependency in libbacktrace

I'm trying to add a dependency in my Makefile at libbacktrace library.
However, it seems I'm not using the correct syntax for it, I've tried:
DEPENDS+= +libbacktrace
But receive the following message -
Package XXXX is missing dependencies for the following libraries
Although the libbacktrace is included in -L (lib) path.
Can anyone offer a solution?
Thank you in advance.
I've never seen a plus sign in a package name, so you probably want this:
DEPENDS += libbacktrace

Problem in compiling in release mode --VC++

I am compiling my project in the release mode in VC++.
I have a .def file where i have declared the setLog and now i
am getting following error
Linking...
Creating library Release/HKL.lib and object Release/HKL.exp
HKL_libinterface.obj : error LNK2001: unresolved external symbol _SCTP_setLog#8
Please help me on the above to fix the problem.
Thanks
It sounds to me like you have a lib file configured in your debug build that is not in the release build. Your setLog() function does not seem to be the function the linker is complaining about - it sounds like it's not finding a function called SCTP_setLog().
Look in the list of libraries you have configured in your project's debug configuration and make sure they are also configured in the release configuration.
If this compiles in Debug mode the most possible reason is that somehow the code where this function is implemented is not included into build - for example, the cpp file where it is implemented has "Excluded from build" set.
As sharptooth mentioned, you most likely are not compiling the above function in your release build. In addition to looking for 'Excluded from build', check if you have any defines set (or not set) that would exclude the missing function from your release build.

Resources