6

I'm trying to compile some code for 32 and 64 bit in the same CMakeLists.txt file. I thought the easiest way to do it would be to use a function. The (static) libraries used in the compilation are also built in the CMakeLists.txt file. However, despite building them in different directories, CMake complains that:

add_library cannot create target "mylib" because another target with
the same name already exists.  The existing target is a static library
created in source directory "/home/chris/proj".

with the problem code being:

cmake_minimum_required (VERSION 2.6 FATAL_ERROR)

enable_language(Fortran)
project(myproj)

set(libfolder ${PROJECT_SOURCE_DIR}/lib/)

function(build bit)

  message("Build library")
  set(BUILD_BINARY_DIR ${PROJECT_BINARY_DIR}/rel-${bit})
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BUILD_BINARY_DIR}/bin)
  add_library(mylib STATIC ${libfolder}/mylib.for)
  set(CMAKE_Fortran_FLAGS "-m${bit}")

endfunction()

build(32)
build(64)

I'm sure I'm missing something obvious, but can't see the problem...

ChrisW
  • 4,970
  • 7
  • 55
  • 92
  • 1
    We had the same issue with our software. We opted for the solution to create an option to decide if it is in 32 or 64. And we build 2 times our software, in each mode. I can provide you an example on how we do that. – Pierre Fourgeaud Jun 26 '13 at 10:21
  • possible duplicate of [Compiling 32-bit vs 64-bit project using CMake](http://stackoverflow.com/questions/4029587/compiling-32-bit-vs-64-bit-project-using-cmake) – mlt Jun 06 '15 at 04:05

2 Answers2

3

As I said in my comment, here is an example of how we did that.

if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
    MESSAGE( "64 bits compiler detected" )
    SET( EX_PLATFORM 64 )
    SET( EX_PLATFORM_NAME "x64" )
else( CMAKE_SIZEOF_VOID_P EQUAL 8 ) 
    MESSAGE( "32 bits compiler detected" )
    SET( EX_PLATFORM 32 )
    SET( EX_PLATFORM_NAME "x86" )
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )

... 

IF( EX_PLATFORM EQUAL 64 )
MESSAGE( "Outputting to lib64 and bin64" )

# ---------- Setup output Directories -------------------------
SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY
   ${YourSoftwarePath}/lib64
   CACHE PATH
   "Single Directory for all Libraries"
   )

# --------- Setup the Executable output Directory -------------
SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY
   ${YourSoftwarePath}/bin64
   CACHE PATH
   "Single Directory for all Executables."
   )

# --------- Setup the Executable output Directory -------------
SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY
   ${YourSoftwarePath}/lib64
   CACHE PATH
   "Single Directory for all static libraries."
   )
ELSE( EX_PLATFORM EQUAL 64 )
# ---------- Setup output Directories -------------------------
SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY
   ${YourSoftwarePath}/lib
   CACHE PATH
   "Single Directory for all Libraries"
   )

# --------- Setup the Executable output Directory -------------
SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY
   ${YourSoftwarePath}/bin
   CACHE PATH
   "Single Directory for all Executables."
   )

# --------- Setup the Executable output Directory -------------
SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY
   ${YourSoftwarePath}/lib
   CACHE PATH
   "Single Directory for all static libraries."
   )
ENDIF( EX_PLATFORM EQUAL 64 )

...


add_library(YourSoftware SHARED
    ${INCLUDES}
    ${SRC}
)

It's working well for us, even in our production process.

It permits top have our configuration ready for both : 32 and 64 bits. After that we have to build in both platform.

Pierre Fourgeaud
  • 14,290
  • 1
  • 38
  • 62
  • 2
    Hmm, what I can't work out is how to build both 32- and 64-bit, including the static libraries, in 1 CMakeLists file. I knew you could detect the architecture of the system, but I'd quite like to build both architectures into subfolders of a release directory – ChrisW Jun 26 '13 at 10:52
  • I don't if you can do that. But you can use the command `install` to copy your result files to the directories wanted. We have a workaround for that too. I will try to make a clear example of that. – Pierre Fourgeaud Jun 26 '13 at 13:54
1

The <name> specified in add_library corresponds to the logical target name and must be globally unique within a project. Hence, you define the same target (mylib) twice, which is forbidden. However you can define two different targets and specify the output name of the target to yield the same library name again:

add_library(mylib${bit} STATIC ${libfolder}/mylib.for)
set_target_properties(mylib${bit} PROPERTIES OUTPUT_NAME mylib)

http://www.cmake.org/cmake/help/v3.0/command/add_library.html http://www.cmake.org/cmake/help/v3.0/command/set_target_properties.html

Robert
  • 719
  • 5
  • 5