如何阻止 CMake 将特定于平台的标志传递给编译器?
How to stop CMake from passing platform specific flags to compiler?
我正在尝试交叉编译我的应用程序。我创建了一个 CMake 文件,该文件使用 Emscripten 构建我的应用程序,它按预期工作。现在我正在修改 CMake 文件以使用 MinGW 编译我的应用程序。问题是 CMake 正在传递 Windows g++ 无法识别的 MacOS 标志。
CMake 将这些选项传递给 g++(以及目标文件和源文件的路径)
-I/usr/local/include -O3 -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -mmacosx-version-min=10.13 -std=gnu++1z
然后我从 g++
得到这个错误
error: unrecognized command line option ‘-mmacosx-version-min=10.13’
有没有一种简单的方法可以阻止 CMake 将 MacOS 特定选项传递给 Windows 编译器?或者 g++ 忽略这些无法识别的选项的方法?
我目前正在使用 find
和 xargs
进行编译。这只是一个临时解决方案,因为我真的很想让它工作!
我在谷歌上搜索了一段时间,似乎找不到解决方案。我尝试使用 make
但它似乎有空间问题。我最后的选择是 bash 脚本。我宁愿不使用 bash 作为构建系统!
这是我的 CMakeLists.txt
文件。 Emscripten 构建有效(定义了 EMBUILD
),但 MinGW
构建无效。我尝试将 CMAKE_SYSTEM_NAME
设置为各种疯狂的值,但这似乎没有任何区别。
cmake_minimum_required(VERSION 3.10)
project(Classic_Tower_Defence)
option(EMBUILD "Build with emscripten, mingw otherwise" YES)
set(EMSCRIPTEN_CC /usr/local/Cellar/emscripten/1.37.37/libexec/emcc)
set(MINGW_CC /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-g++)
if(EMBUILD)
set(CC ${EMSCRIPTEN_CC})
else()
set(CC ${MINGW_CC})
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_CROSSCOMPILING YES)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_COMPILER ${CC})
set(CMAKE_C_COMPILER ${CC})
set(RES_PATH /Users/indikernick/Library/Developer/Xcode/DerivedData/Classic_Tower_Defence-dcezwdbogljnithjukklclgyblij/Build/Products/Debug/Classic\ Tower\ Defence.app/Contents/Resources)
#if (CMAKE_BUILD_TYPE MATCHES RELEASE)
set(EXTRA_FLAGS "-O3 --closure 1")
#else()
# set(EXTRA_FLAGS "-s DEMANGLE_SUPPORT=1")
#endif()
if (EMBUILD)
set(LINKER_FLAGS " \
${EXTRA_FLAGS} \
-s WASM=1 \
-s USE_WEBGL2=1 \
-s USE_SDL=2 \
-s TOTAL_MEMORY=805306368 \
-s DISABLE_EXCEPTION_CATCHING=0 \
--pre-js '${PROJECT_SOURCE_DIR}/Webpage/init.js' \
--shell-file '${PROJECT_SOURCE_DIR}/Webpage/index.html' \
--preload-file '${RES_PATH}@/' \
")
set(CMAKE_CXX_FLAGS " \
${EXTRA_FLAGS} \
-msse3 \
")
else()
# -static-libstdc++ -static-libgcc -L./ -Wl,-rpath,./ -lopengl32 -lSDL2 -lSDL2_Mixer -lglew32 -o main.exe
set(LINKER_FLAGS " \
-static-libstdc++ \
-static-libgcc \
-L../lib \
-Wl,-rpath,./ \
-lopengl32 \
-lSDL2 \
-lSDL2_Mixer \
-lglew32 \
")
set(CMAKE_CXX_FLAGS "-O3 -DGLM_FORCE_CTOR_INIT")
endif()
include_directories(/usr/local/include/)
set(SOURCE_FILES
"Classic Tower Defence/Game/create spawner.cpp"
"Classic Tower Defence/Game/unit death system.cpp"
"Classic Tower Defence/Game/game info model.cpp"
"Classic Tower Defence/Game/game info view.cpp"
"Classic Tower Defence/Game/splash damage system.cpp"
"Classic Tower Defence/Game/tower beam rendering system.cpp"
"Classic Tower Defence/Game/aura damage system.cpp"
"Classic Tower Defence/Game/load map.cpp"
"Classic Tower Defence/Game/cursor systems.cpp"
"Classic Tower Defence/Game/tower reset rof system.cpp"
"Classic Tower Defence/Game/base damage system.cpp"
"Classic Tower Defence/Game/unit death sound system.cpp"
"Classic Tower Defence/Game/unit motion system.cpp"
"Classic Tower Defence/Game/count live units.cpp"
"Classic Tower Defence/Game/tower beam anim system.cpp"
"Classic Tower Defence/Game/load towers.cpp"
"Classic Tower Defence/Game/turret damage system.cpp"
"Classic Tower Defence/Game/tower sound system.cpp"
"Classic Tower Defence/Game/load prototype.cpp"
"Classic Tower Defence/Game/stats controller.cpp"
"Classic Tower Defence/Game/unit rendering system.cpp"
"Classic Tower Defence/Game/unit death anim system.cpp"
"Classic Tower Defence/Game/tower aura rendering system.cpp"
"Classic Tower Defence/Game/tower aim system.cpp"
"Classic Tower Defence/Game/unit damage system.cpp"
"Classic Tower Defence/Game/slow effect system.cpp"
"Classic Tower Defence/Game/game logic.cpp"
"Classic Tower Defence/Game/next wave.cpp"
"Classic Tower Defence/Game/unit regen system.cpp"
"Classic Tower Defence/Game/unit effect system.cpp"
"Classic Tower Defence/Game/poison effect system.cpp"
"Classic Tower Defence/Game/tower rendering system.cpp"
"Classic Tower Defence/Game/load waves.cpp"
"Classic Tower Defence/Game/tower projectile rendering system.cpp"
"Classic Tower Defence/Game/unit health rendering system.cpp"
"Classic Tower Defence/Game/unit walk anim system.cpp"
"Classic Tower Defence/Game/init map info.cpp"
"Classic Tower Defence/Game/load level.cpp"
"Classic Tower Defence/Game/sound queue.cpp"
"Classic Tower Defence/Game/unit death rendering system.cpp"
"Classic Tower Defence/Game/tower rof system.cpp"
"Classic Tower Defence/Game/stats view.cpp"
"Classic Tower Defence/Game/spawner timing system.cpp"
"Classic Tower Defence/Game/load base.cpp"
"Classic Tower Defence/Game/stats model.cpp"
"Classic Tower Defence/Game/spawner system.cpp"
"Classic Tower Defence/Game/preview entity.cpp"
"Classic Tower Defence/Game/game view.cpp"
"Classic Tower Defence/Game/create tower.cpp"
"Classic Tower Defence/Game/ui view.cpp"
"Classic Tower Defence/Game/get wave info.cpp"
"Classic Tower Defence/Game/firing anim system.cpp"
"Classic Tower Defence/Game/create level.cpp"
"Classic Tower Defence/Game/tower range rendering system.cpp"
"Classic Tower Defence/Game/load spawner.cpp"
"Classic Tower Defence/Game/map rendering system.cpp"
"Classic Tower Defence/Game/app.cpp"
"Classic Tower Defence/main.cpp"
)
add_executable(Classic_Tower_Defence ${SOURCE_FILES})
if (EMBUILD)
set_target_properties(Classic_Tower_Defence PROPERTIES OUTPUT_NAME index.html)
else()
set_target_properties(Classic_Tower_Defence PROPERTIES OUTPUT_NAME main.exe)
endif()
set_target_properties(Classic_Tower_Defence PROPERTIES LINK_FLAGS "${LINKER_FLAGS}")
您可能会说我不是 CMake 专家!我应该使用生成器表达式并查找模块。我真的不知道如何处理字符串并确保在正确的位置有反斜杠和引号。但它有效(一半有效)
将我的评论变成答案
我已经成功地 the following minimal example - assuming from the visible paths in your code that you did install mingw 通过例如brew install mingw-w64
:
编辑:同样的程序也成功地用 this OpenGL example 测试了。
$ git clone https://github.com/jameskbride/cmake-hello-world.git
Cloning into 'cmake-hello-world'...
remote: Counting objects: 56, done.
remote: Total 56 (delta 0), reused 0 (delta 0), pack-reused 56
Unpacking objects: 100% (56/56), done.
$ cd cmake-hello-world/
$ mkdir build
$ cd build
$ export CC=/usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-gcc
$ export CXX=/usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-g++
$ cmake -D CMAKE_SYSTEM_NAME=Windows -G "Unix Makefiles" ..
-- The C compiler identification is GNU 7.3.0
-- The CXX compiler identification is GNU 7.3.0
-- Check for working C compiler: /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-gcc
-- Check for working C compiler: /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-g++
-- Check for working CXX compiler: /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /.../cmake-hello-world/build
$ cmake --build .
Scanning dependencies of target Hello
[ 25%] Building CXX object Hello/CMakeFiles/Hello.dir/Speaker.cpp.obj
[ 50%] Linking CXX static library libHello.a
[ 50%] Built target Hello
Scanning dependencies of target CMakeHelloWorld
[ 75%] Building CXX object CMakeFiles/CMakeHelloWorld.dir/HelloWorld.cpp.obj
[100%] Linking CXX executable CMakeHelloWorld.exe
[100%] Built target CMakeHelloWorld
主要是编译器和system/platform变量必须在project()
命令之前定义。还有 CMAKE_SYSTEM_NAME
is the key to enable cross compiling.
正如@Tsyvarev 评论的那样,这通常在 toolchain 文件中完成(而不是 "pollute" 您的跨平台 CMake 代码)。
您的完整代码更适合在 Code Review Stack Exchange 站点上进行审查。
我正在尝试交叉编译我的应用程序。我创建了一个 CMake 文件,该文件使用 Emscripten 构建我的应用程序,它按预期工作。现在我正在修改 CMake 文件以使用 MinGW 编译我的应用程序。问题是 CMake 正在传递 Windows g++ 无法识别的 MacOS 标志。
CMake 将这些选项传递给 g++(以及目标文件和源文件的路径)
-I/usr/local/include -O3 -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -mmacosx-version-min=10.13 -std=gnu++1z
然后我从 g++
得到这个错误error: unrecognized command line option ‘-mmacosx-version-min=10.13’
有没有一种简单的方法可以阻止 CMake 将 MacOS 特定选项传递给 Windows 编译器?或者 g++ 忽略这些无法识别的选项的方法?
我目前正在使用 find
和 xargs
进行编译。这只是一个临时解决方案,因为我真的很想让它工作!
我在谷歌上搜索了一段时间,似乎找不到解决方案。我尝试使用 make
但它似乎有空间问题。我最后的选择是 bash 脚本。我宁愿不使用 bash 作为构建系统!
这是我的 CMakeLists.txt
文件。 Emscripten 构建有效(定义了 EMBUILD
),但 MinGW
构建无效。我尝试将 CMAKE_SYSTEM_NAME
设置为各种疯狂的值,但这似乎没有任何区别。
cmake_minimum_required(VERSION 3.10)
project(Classic_Tower_Defence)
option(EMBUILD "Build with emscripten, mingw otherwise" YES)
set(EMSCRIPTEN_CC /usr/local/Cellar/emscripten/1.37.37/libexec/emcc)
set(MINGW_CC /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-g++)
if(EMBUILD)
set(CC ${EMSCRIPTEN_CC})
else()
set(CC ${MINGW_CC})
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_CROSSCOMPILING YES)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_COMPILER ${CC})
set(CMAKE_C_COMPILER ${CC})
set(RES_PATH /Users/indikernick/Library/Developer/Xcode/DerivedData/Classic_Tower_Defence-dcezwdbogljnithjukklclgyblij/Build/Products/Debug/Classic\ Tower\ Defence.app/Contents/Resources)
#if (CMAKE_BUILD_TYPE MATCHES RELEASE)
set(EXTRA_FLAGS "-O3 --closure 1")
#else()
# set(EXTRA_FLAGS "-s DEMANGLE_SUPPORT=1")
#endif()
if (EMBUILD)
set(LINKER_FLAGS " \
${EXTRA_FLAGS} \
-s WASM=1 \
-s USE_WEBGL2=1 \
-s USE_SDL=2 \
-s TOTAL_MEMORY=805306368 \
-s DISABLE_EXCEPTION_CATCHING=0 \
--pre-js '${PROJECT_SOURCE_DIR}/Webpage/init.js' \
--shell-file '${PROJECT_SOURCE_DIR}/Webpage/index.html' \
--preload-file '${RES_PATH}@/' \
")
set(CMAKE_CXX_FLAGS " \
${EXTRA_FLAGS} \
-msse3 \
")
else()
# -static-libstdc++ -static-libgcc -L./ -Wl,-rpath,./ -lopengl32 -lSDL2 -lSDL2_Mixer -lglew32 -o main.exe
set(LINKER_FLAGS " \
-static-libstdc++ \
-static-libgcc \
-L../lib \
-Wl,-rpath,./ \
-lopengl32 \
-lSDL2 \
-lSDL2_Mixer \
-lglew32 \
")
set(CMAKE_CXX_FLAGS "-O3 -DGLM_FORCE_CTOR_INIT")
endif()
include_directories(/usr/local/include/)
set(SOURCE_FILES
"Classic Tower Defence/Game/create spawner.cpp"
"Classic Tower Defence/Game/unit death system.cpp"
"Classic Tower Defence/Game/game info model.cpp"
"Classic Tower Defence/Game/game info view.cpp"
"Classic Tower Defence/Game/splash damage system.cpp"
"Classic Tower Defence/Game/tower beam rendering system.cpp"
"Classic Tower Defence/Game/aura damage system.cpp"
"Classic Tower Defence/Game/load map.cpp"
"Classic Tower Defence/Game/cursor systems.cpp"
"Classic Tower Defence/Game/tower reset rof system.cpp"
"Classic Tower Defence/Game/base damage system.cpp"
"Classic Tower Defence/Game/unit death sound system.cpp"
"Classic Tower Defence/Game/unit motion system.cpp"
"Classic Tower Defence/Game/count live units.cpp"
"Classic Tower Defence/Game/tower beam anim system.cpp"
"Classic Tower Defence/Game/load towers.cpp"
"Classic Tower Defence/Game/turret damage system.cpp"
"Classic Tower Defence/Game/tower sound system.cpp"
"Classic Tower Defence/Game/load prototype.cpp"
"Classic Tower Defence/Game/stats controller.cpp"
"Classic Tower Defence/Game/unit rendering system.cpp"
"Classic Tower Defence/Game/unit death anim system.cpp"
"Classic Tower Defence/Game/tower aura rendering system.cpp"
"Classic Tower Defence/Game/tower aim system.cpp"
"Classic Tower Defence/Game/unit damage system.cpp"
"Classic Tower Defence/Game/slow effect system.cpp"
"Classic Tower Defence/Game/game logic.cpp"
"Classic Tower Defence/Game/next wave.cpp"
"Classic Tower Defence/Game/unit regen system.cpp"
"Classic Tower Defence/Game/unit effect system.cpp"
"Classic Tower Defence/Game/poison effect system.cpp"
"Classic Tower Defence/Game/tower rendering system.cpp"
"Classic Tower Defence/Game/load waves.cpp"
"Classic Tower Defence/Game/tower projectile rendering system.cpp"
"Classic Tower Defence/Game/unit health rendering system.cpp"
"Classic Tower Defence/Game/unit walk anim system.cpp"
"Classic Tower Defence/Game/init map info.cpp"
"Classic Tower Defence/Game/load level.cpp"
"Classic Tower Defence/Game/sound queue.cpp"
"Classic Tower Defence/Game/unit death rendering system.cpp"
"Classic Tower Defence/Game/tower rof system.cpp"
"Classic Tower Defence/Game/stats view.cpp"
"Classic Tower Defence/Game/spawner timing system.cpp"
"Classic Tower Defence/Game/load base.cpp"
"Classic Tower Defence/Game/stats model.cpp"
"Classic Tower Defence/Game/spawner system.cpp"
"Classic Tower Defence/Game/preview entity.cpp"
"Classic Tower Defence/Game/game view.cpp"
"Classic Tower Defence/Game/create tower.cpp"
"Classic Tower Defence/Game/ui view.cpp"
"Classic Tower Defence/Game/get wave info.cpp"
"Classic Tower Defence/Game/firing anim system.cpp"
"Classic Tower Defence/Game/create level.cpp"
"Classic Tower Defence/Game/tower range rendering system.cpp"
"Classic Tower Defence/Game/load spawner.cpp"
"Classic Tower Defence/Game/map rendering system.cpp"
"Classic Tower Defence/Game/app.cpp"
"Classic Tower Defence/main.cpp"
)
add_executable(Classic_Tower_Defence ${SOURCE_FILES})
if (EMBUILD)
set_target_properties(Classic_Tower_Defence PROPERTIES OUTPUT_NAME index.html)
else()
set_target_properties(Classic_Tower_Defence PROPERTIES OUTPUT_NAME main.exe)
endif()
set_target_properties(Classic_Tower_Defence PROPERTIES LINK_FLAGS "${LINKER_FLAGS}")
您可能会说我不是 CMake 专家!我应该使用生成器表达式并查找模块。我真的不知道如何处理字符串并确保在正确的位置有反斜杠和引号。但它有效(一半有效)
将我的评论变成答案
我已经成功地 the following minimal example - assuming from the visible paths in your code that you did install mingw 通过例如brew install mingw-w64
:
编辑:同样的程序也成功地用 this OpenGL example 测试了。
$ git clone https://github.com/jameskbride/cmake-hello-world.git
Cloning into 'cmake-hello-world'...
remote: Counting objects: 56, done.
remote: Total 56 (delta 0), reused 0 (delta 0), pack-reused 56
Unpacking objects: 100% (56/56), done.
$ cd cmake-hello-world/
$ mkdir build
$ cd build
$ export CC=/usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-gcc
$ export CXX=/usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-g++
$ cmake -D CMAKE_SYSTEM_NAME=Windows -G "Unix Makefiles" ..
-- The C compiler identification is GNU 7.3.0
-- The CXX compiler identification is GNU 7.3.0
-- Check for working C compiler: /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-gcc
-- Check for working C compiler: /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-g++
-- Check for working CXX compiler: /usr/local/Cellar/mingw-w64/5.0.3_3/toolchain-x86_64/bin/x86_64-w64-mingw32-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /.../cmake-hello-world/build
$ cmake --build .
Scanning dependencies of target Hello
[ 25%] Building CXX object Hello/CMakeFiles/Hello.dir/Speaker.cpp.obj
[ 50%] Linking CXX static library libHello.a
[ 50%] Built target Hello
Scanning dependencies of target CMakeHelloWorld
[ 75%] Building CXX object CMakeFiles/CMakeHelloWorld.dir/HelloWorld.cpp.obj
[100%] Linking CXX executable CMakeHelloWorld.exe
[100%] Built target CMakeHelloWorld
主要是编译器和system/platform变量必须在project()
命令之前定义。还有 CMAKE_SYSTEM_NAME
is the key to enable cross compiling.
正如@Tsyvarev 评论的那样,这通常在 toolchain 文件中完成(而不是 "pollute" 您的跨平台 CMake 代码)。
您的完整代码更适合在 Code Review Stack Exchange 站点上进行审查。